14b6f4942fcef3300b407d9a07a680c07b162333fWei-Ta Chen/*
24b6f4942fcef3300b407d9a07a680c07b162333fWei-Ta Chen * Copyright (C) 2009 The Android Open Source Project
34b6f4942fcef3300b407d9a07a680c07b162333fWei-Ta Chen *
44b6f4942fcef3300b407d9a07a680c07b162333fWei-Ta Chen * Licensed under the Apache License, Version 2.0 (the "License");
54b6f4942fcef3300b407d9a07a680c07b162333fWei-Ta Chen * you may not use this file except in compliance with the License.
64b6f4942fcef3300b407d9a07a680c07b162333fWei-Ta Chen * You may obtain a copy of the License at
74b6f4942fcef3300b407d9a07a680c07b162333fWei-Ta Chen *
84b6f4942fcef3300b407d9a07a680c07b162333fWei-Ta Chen *      http://www.apache.org/licenses/LICENSE-2.0
94b6f4942fcef3300b407d9a07a680c07b162333fWei-Ta Chen *
104b6f4942fcef3300b407d9a07a680c07b162333fWei-Ta Chen * Unless required by applicable law or agreed to in writing, software
114b6f4942fcef3300b407d9a07a680c07b162333fWei-Ta Chen * distributed under the License is distributed on an "AS IS" BASIS,
124b6f4942fcef3300b407d9a07a680c07b162333fWei-Ta Chen * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
134b6f4942fcef3300b407d9a07a680c07b162333fWei-Ta Chen * See the License for the specific language governing permissions and
144b6f4942fcef3300b407d9a07a680c07b162333fWei-Ta Chen * limitations under the License.
154b6f4942fcef3300b407d9a07a680c07b162333fWei-Ta Chen */
164b6f4942fcef3300b407d9a07a680c07b162333fWei-Ta Chen
174b6f4942fcef3300b407d9a07a680c07b162333fWei-Ta Chen#define LOG_TAG "OmxJpegDecoder"
184b6f4942fcef3300b407d9a07a680c07b162333fWei-Ta Chen#include <sys/time.h>
194b6f4942fcef3300b407d9a07a680c07b162333fWei-Ta Chen#include <utils/Log.h>
204b6f4942fcef3300b407d9a07a680c07b162333fWei-Ta Chen
214b6f4942fcef3300b407d9a07a680c07b162333fWei-Ta Chen#include <binder/ProcessState.h>
224b6f4942fcef3300b407d9a07a680c07b162333fWei-Ta Chen
234b6f4942fcef3300b407d9a07a680c07b162333fWei-Ta Chen#include "SkBitmap.h"
244b6f4942fcef3300b407d9a07a680c07b162333fWei-Ta Chen#include "SkImageDecoder.h"
254b6f4942fcef3300b407d9a07a680c07b162333fWei-Ta Chen#include "SkStream.h"
264b6f4942fcef3300b407d9a07a680c07b162333fWei-Ta Chen#include "omx_jpeg_decoder.h"
274b6f4942fcef3300b407d9a07a680c07b162333fWei-Ta Chen
28b355012797dfd503eee9f80ed06bc30a17cc3318Wei-Ta Chenclass SkJPEGImageDecoder : public SkImageDecoder {
29b355012797dfd503eee9f80ed06bc30a17cc3318Wei-Ta Chenpublic:
30b355012797dfd503eee9f80ed06bc30a17cc3318Wei-Ta Chen    virtual Format getFormat() const {
31b355012797dfd503eee9f80ed06bc30a17cc3318Wei-Ta Chen        return kJPEG_Format;
32b355012797dfd503eee9f80ed06bc30a17cc3318Wei-Ta Chen    }
33b355012797dfd503eee9f80ed06bc30a17cc3318Wei-Ta Chen
34b355012797dfd503eee9f80ed06bc30a17cc3318Wei-Ta Chenprotected:
35945a9df6e31cf951d6f323a85a7e75c19c7f60f6Mike Reed    virtual bool onDecode(SkStream* stream, SkBitmap* bm, Mode);
36b355012797dfd503eee9f80ed06bc30a17cc3318Wei-Ta Chen};
37b355012797dfd503eee9f80ed06bc30a17cc3318Wei-Ta Chen
384b6f4942fcef3300b407d9a07a680c07b162333fWei-Ta Chenint nullObjectReturn(const char msg[]) {
394b6f4942fcef3300b407d9a07a680c07b162333fWei-Ta Chen    if (msg) {
404b6f4942fcef3300b407d9a07a680c07b162333fWei-Ta Chen        SkDebugf("--- %s\n", msg);
414b6f4942fcef3300b407d9a07a680c07b162333fWei-Ta Chen    }
424b6f4942fcef3300b407d9a07a680c07b162333fWei-Ta Chen    return -1;
434b6f4942fcef3300b407d9a07a680c07b162333fWei-Ta Chen}
444b6f4942fcef3300b407d9a07a680c07b162333fWei-Ta Chen
454b6f4942fcef3300b407d9a07a680c07b162333fWei-Ta Chenstatic int64_t getNowUs() {
464b6f4942fcef3300b407d9a07a680c07b162333fWei-Ta Chen    struct timeval tv;
474b6f4942fcef3300b407d9a07a680c07b162333fWei-Ta Chen    gettimeofday(&tv, NULL);
484b6f4942fcef3300b407d9a07a680c07b162333fWei-Ta Chen
494b6f4942fcef3300b407d9a07a680c07b162333fWei-Ta Chen    return tv.tv_usec + (int64_t) tv.tv_sec * 1000000;
504b6f4942fcef3300b407d9a07a680c07b162333fWei-Ta Chen}
514b6f4942fcef3300b407d9a07a680c07b162333fWei-Ta Chen
524b6f4942fcef3300b407d9a07a680c07b162333fWei-Ta Chenint testDecodeBounds(SkImageDecoder* decoder, SkStream* stream,
534b6f4942fcef3300b407d9a07a680c07b162333fWei-Ta Chen        SkBitmap* bitmap) {
544b6f4942fcef3300b407d9a07a680c07b162333fWei-Ta Chen    int64_t startTime = getNowUs();
554b6f4942fcef3300b407d9a07a680c07b162333fWei-Ta Chen    SkBitmap::Config prefConfig = SkBitmap::kARGB_8888_Config;
564b6f4942fcef3300b407d9a07a680c07b162333fWei-Ta Chen    SkImageDecoder::Mode decodeMode = SkImageDecoder::kDecodeBounds_Mode;
574b6f4942fcef3300b407d9a07a680c07b162333fWei-Ta Chen
584b6f4942fcef3300b407d9a07a680c07b162333fWei-Ta Chen    // Decode the input stream and then use the bitmap.
594b6f4942fcef3300b407d9a07a680c07b162333fWei-Ta Chen    if (!decoder->decode(stream, bitmap, prefConfig, decodeMode)) {
604b6f4942fcef3300b407d9a07a680c07b162333fWei-Ta Chen        return nullObjectReturn("decoder->decode returned false");
614b6f4942fcef3300b407d9a07a680c07b162333fWei-Ta Chen    } else {
624b6f4942fcef3300b407d9a07a680c07b162333fWei-Ta Chen        int64_t delay = getNowUs() - startTime;
634b6f4942fcef3300b407d9a07a680c07b162333fWei-Ta Chen        printf("WidthxHeight: %dx%d\n", bitmap->width(), bitmap->height());
644b6f4942fcef3300b407d9a07a680c07b162333fWei-Ta Chen        printf("Decoding Time in BoundsMode %.1f msec.\n", delay / 1000.0f);
654b6f4942fcef3300b407d9a07a680c07b162333fWei-Ta Chen        return 0;
664b6f4942fcef3300b407d9a07a680c07b162333fWei-Ta Chen    }
674b6f4942fcef3300b407d9a07a680c07b162333fWei-Ta Chen}
684b6f4942fcef3300b407d9a07a680c07b162333fWei-Ta Chen
694b6f4942fcef3300b407d9a07a680c07b162333fWei-Ta Chenint testDecodePixels(SkImageDecoder* decoder, SkStream* stream,
704b6f4942fcef3300b407d9a07a680c07b162333fWei-Ta Chen        SkBitmap* bitmap) {
714b6f4942fcef3300b407d9a07a680c07b162333fWei-Ta Chen    int64_t startTime = getNowUs();
724b6f4942fcef3300b407d9a07a680c07b162333fWei-Ta Chen    SkBitmap::Config prefConfig = SkBitmap::kARGB_8888_Config;
734b6f4942fcef3300b407d9a07a680c07b162333fWei-Ta Chen    SkImageDecoder::Mode decodeMode = SkImageDecoder::kDecodePixels_Mode;
744b6f4942fcef3300b407d9a07a680c07b162333fWei-Ta Chen
754b6f4942fcef3300b407d9a07a680c07b162333fWei-Ta Chen    // Decode the input stream and then use the bitmap.
764b6f4942fcef3300b407d9a07a680c07b162333fWei-Ta Chen    if (!decoder->decode(stream, bitmap, prefConfig, decodeMode)) {
774b6f4942fcef3300b407d9a07a680c07b162333fWei-Ta Chen        return nullObjectReturn("decoder->decode returned false");
784b6f4942fcef3300b407d9a07a680c07b162333fWei-Ta Chen    } else {
794b6f4942fcef3300b407d9a07a680c07b162333fWei-Ta Chen        int64_t delay = getNowUs() - startTime;
804b6f4942fcef3300b407d9a07a680c07b162333fWei-Ta Chen        printf("Decoding Time in PixelsMode %.1f msec.\n", delay / 1000.0f);
81987dbde838014e5f0c55a63acdd2a9a002b140ccAndreas Huber        const char* filename = "/sdcard/omxJpegDecodedBitmap.rgba";
824b6f4942fcef3300b407d9a07a680c07b162333fWei-Ta Chen        return storeBitmapToFile(bitmap, filename);
834b6f4942fcef3300b407d9a07a680c07b162333fWei-Ta Chen    }
844b6f4942fcef3300b407d9a07a680c07b162333fWei-Ta Chen}
854b6f4942fcef3300b407d9a07a680c07b162333fWei-Ta Chen
864b6f4942fcef3300b407d9a07a680c07b162333fWei-Ta Chenint testDecoder(SkImageDecoder* decoder, char* filename) {
874b6f4942fcef3300b407d9a07a680c07b162333fWei-Ta Chen    // test DecodeMode == Pixels
884b6f4942fcef3300b407d9a07a680c07b162333fWei-Ta Chen    SkStream* stream = new SkFILEStream(filename);
894b6f4942fcef3300b407d9a07a680c07b162333fWei-Ta Chen    SkBitmap* bitmap = new SkBitmap;
904b6f4942fcef3300b407d9a07a680c07b162333fWei-Ta Chen    testDecodePixels(decoder, stream, bitmap);
914b6f4942fcef3300b407d9a07a680c07b162333fWei-Ta Chen    delete bitmap;
924b6f4942fcef3300b407d9a07a680c07b162333fWei-Ta Chen
934b6f4942fcef3300b407d9a07a680c07b162333fWei-Ta Chen    // test DecodeMode == Bounds
944b6f4942fcef3300b407d9a07a680c07b162333fWei-Ta Chen    stream = new SkFILEStream(filename);
954b6f4942fcef3300b407d9a07a680c07b162333fWei-Ta Chen    bitmap = new SkBitmap;
964b6f4942fcef3300b407d9a07a680c07b162333fWei-Ta Chen    testDecodeBounds(decoder, stream, bitmap);
974b6f4942fcef3300b407d9a07a680c07b162333fWei-Ta Chen    delete bitmap;
984b6f4942fcef3300b407d9a07a680c07b162333fWei-Ta Chen
994b6f4942fcef3300b407d9a07a680c07b162333fWei-Ta Chen    delete decoder;
1004b6f4942fcef3300b407d9a07a680c07b162333fWei-Ta Chen    return 0;
1014b6f4942fcef3300b407d9a07a680c07b162333fWei-Ta Chen}
1024b6f4942fcef3300b407d9a07a680c07b162333fWei-Ta Chen
1034b6f4942fcef3300b407d9a07a680c07b162333fWei-Ta Chenint main(int argc, char** argv) {
1044b6f4942fcef3300b407d9a07a680c07b162333fWei-Ta Chen    android::ProcessState::self()->startThreadPool();
1054b6f4942fcef3300b407d9a07a680c07b162333fWei-Ta Chen
1064b6f4942fcef3300b407d9a07a680c07b162333fWei-Ta Chen    printf("Decoding jpeg with libjpeg...\n");
1074b6f4942fcef3300b407d9a07a680c07b162333fWei-Ta Chen    SkJPEGImageDecoder* libjpeg = new SkJPEGImageDecoder;
1084b6f4942fcef3300b407d9a07a680c07b162333fWei-Ta Chen    testDecoder(libjpeg, argv[1]);
1094b6f4942fcef3300b407d9a07a680c07b162333fWei-Ta Chen
1104b6f4942fcef3300b407d9a07a680c07b162333fWei-Ta Chen    printf("\nDecoding jpeg with OMX...\n");
1114b6f4942fcef3300b407d9a07a680c07b162333fWei-Ta Chen    OmxJpegImageDecoder* omx = new OmxJpegImageDecoder;
1124b6f4942fcef3300b407d9a07a680c07b162333fWei-Ta Chen    testDecoder(omx, argv[1]);
1134b6f4942fcef3300b407d9a07a680c07b162333fWei-Ta Chen    return 0;
1144b6f4942fcef3300b407d9a07a680c07b162333fWei-Ta Chen}
115