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