1 /* 2 * Copyright (C) Texas Instruments - http://www.ti.com/ 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 /** 18 * @file Encoder_libjpeg.h 19 * 20 * This defines API for camerahal to encode YUV using libjpeg 21 * 22 */ 23 24 #ifndef ANDROID_CAMERA_HARDWARE_ENCODER_LIBJPEG_H 25 #define ANDROID_CAMERA_HARDWARE_ENCODER_LIBJPEG_H 26 27 #include <utils/threads.h> 28 #include <utils/RefBase.h> 29 30 extern "C" { 31 #include "jhead.h" 32 } 33 34 #define CANCEL_TIMEOUT 3000000 // 3 seconds 35 36 namespace android { 37 /** 38 * libjpeg encoder class - uses libjpeg to encode yuv 39 */ 40 41 #define MAX_EXIF_TAGS_SUPPORTED 30 42 typedef void (*encoder_libjpeg_callback_t) (void* main_jpeg, 43 void* thumb_jpeg, 44 CameraFrame::FrameType type, 45 void* cookie1, 46 void* cookie2, 47 void* cookie3, 48 bool canceled); 49 50 // these have to match strings defined in external/jhead/exif.c 51 static const char TAG_MODEL[] = "Model"; 52 static const char TAG_MAKE[] = "Make"; 53 static const char TAG_FOCALLENGTH[] = "FocalLength"; 54 static const char TAG_DATETIME[] = "DateTime"; 55 static const char TAG_IMAGE_WIDTH[] = "ImageWidth"; 56 static const char TAG_IMAGE_LENGTH[] = "ImageLength"; 57 static const char TAG_GPS_LAT[] = "GPSLatitude"; 58 static const char TAG_GPS_LAT_REF[] = "GPSLatitudeRef"; 59 static const char TAG_GPS_LONG[] = "GPSLongitude"; 60 static const char TAG_GPS_LONG_REF[] = "GPSLongitudeRef"; 61 static const char TAG_GPS_ALT[] = "GPSAltitude"; 62 static const char TAG_GPS_ALT_REF[] = "GPSAltitudeRef"; 63 static const char TAG_GPS_MAP_DATUM[] = "GPSMapDatum"; 64 static const char TAG_GPS_PROCESSING_METHOD[] = "GPSProcessingMethod"; 65 static const char TAG_GPS_VERSION_ID[] = "GPSVersionID"; 66 static const char TAG_GPS_TIMESTAMP[] = "GPSTimeStamp"; 67 static const char TAG_GPS_DATESTAMP[] = "GPSDateStamp"; 68 static const char TAG_ORIENTATION[] = "Orientation"; 69 static const char TAG_FLASH[] = "Flash"; 70 static const char TAG_DIGITALZOOMRATIO[] = "DigitalZoomRatio"; 71 static const char TAG_EXPOSURETIME[] = "ExposureTime"; 72 static const char TAG_APERTURE[] = "ApertureValue"; 73 static const char TAG_ISO_EQUIVALENT[] = "ISOSpeedRatings"; 74 static const char TAG_WHITEBALANCE[] = "WhiteBalance"; 75 static const char TAG_LIGHT_SOURCE[] = "LightSource"; 76 static const char TAG_METERING_MODE[] = "MeteringMode"; 77 static const char TAG_EXPOSURE_PROGRAM[] = "ExposureProgram"; 78 static const char TAG_COLOR_SPACE[] = "ColorSpace"; 79 static const char TAG_CPRS_BITS_PER_PIXEL[] = "CompressedBitsPerPixel"; 80 static const char TAG_FNUMBER[] = "FNumber"; 81 static const char TAG_SHUTTERSPEED[] = "ShutterSpeedValue"; 82 static const char TAG_SENSING_METHOD[] = "SensingMethod"; 83 static const char TAG_CUSTOM_RENDERED[] = "CustomRendered"; 84 85 class ExifElementsTable { 86 public: ExifElementsTable()87 ExifElementsTable() : 88 gps_tag_count(0), exif_tag_count(0), position(0), 89 jpeg_opened(false), has_datetime_tag(false) { } 90 ~ExifElementsTable(); 91 92 status_t insertElement(const char* tag, const char* value); 93 void insertExifToJpeg(unsigned char* jpeg, size_t jpeg_size); 94 status_t insertExifThumbnailImage(const char*, int); 95 void saveJpeg(unsigned char* picture, size_t jpeg_size); 96 static const char* degreesToExifOrientation(unsigned int); 97 static void stringToRational(const char*, unsigned int*, unsigned int*); 98 static bool isAsciiTag(const char* tag); 99 private: 100 ExifElement_t table[MAX_EXIF_TAGS_SUPPORTED]; 101 unsigned int gps_tag_count; 102 unsigned int exif_tag_count; 103 unsigned int position; 104 bool jpeg_opened; 105 bool has_datetime_tag; 106 }; 107 108 class Encoder_libjpeg : public Thread { 109 /* public member types and variables */ 110 public: 111 struct params { 112 uint8_t* src; 113 int src_size; 114 uint8_t* dst; 115 int dst_size; 116 int quality; 117 int in_width; 118 int in_height; 119 int out_width; 120 int out_height; 121 int right_crop; 122 int start_offset; 123 const char* format; 124 size_t jpeg_size; 125 }; 126 /* public member functions */ 127 public: Encoder_libjpeg(params * main_jpeg,params * tn_jpeg,encoder_libjpeg_callback_t cb,CameraFrame::FrameType type,void * cookie1,void * cookie2,void * cookie3)128 Encoder_libjpeg(params* main_jpeg, 129 params* tn_jpeg, 130 encoder_libjpeg_callback_t cb, 131 CameraFrame::FrameType type, 132 void* cookie1, 133 void* cookie2, 134 void* cookie3) 135 : Thread(false), mMainInput(main_jpeg), mThumbnailInput(tn_jpeg), mCb(cb), 136 mCancelEncoding(false), mCookie1(cookie1), mCookie2(cookie2), mCookie3(cookie3), 137 mType(type), mThumb(NULL) { 138 this->incStrong(this); 139 mCancelSem.Create(0); 140 } 141 ~Encoder_libjpeg()142 ~Encoder_libjpeg() { 143 CAMHAL_LOGVB("~Encoder_libjpeg(%p)", this); 144 } 145 threadLoop()146 virtual bool threadLoop() { 147 size_t size = 0; 148 sp<Encoder_libjpeg> tn = NULL; 149 if (mThumbnailInput) { 150 // start thread to encode thumbnail 151 mThumb = new Encoder_libjpeg(mThumbnailInput, NULL, NULL, mType, NULL, NULL, NULL); 152 mThumb->run(); 153 } 154 155 // encode our main image 156 size = encode(mMainInput); 157 158 // signal cancel semaphore incase somebody is waiting 159 mCancelSem.Signal(); 160 161 // check if it is main jpeg thread 162 if(mThumb.get()) { 163 // wait until tn jpeg thread exits. 164 mThumb->join(); 165 mThumb.clear(); 166 mThumb = NULL; 167 } 168 169 if(mCb) { 170 mCb(mMainInput, mThumbnailInput, mType, mCookie1, mCookie2, mCookie3, mCancelEncoding); 171 } 172 173 // encoder thread runs, self-destructs, and then exits 174 this->decStrong(this); 175 return false; 176 } 177 cancel()178 void cancel() { 179 mCancelEncoding = true; 180 if (mThumb.get()) { 181 mThumb->cancel(); 182 mCancelSem.WaitTimeout(CANCEL_TIMEOUT); 183 } 184 } 185 getCookies(void ** cookie1,void ** cookie2,void ** cookie3)186 void getCookies(void **cookie1, void **cookie2, void **cookie3) { 187 if (cookie1) *cookie1 = mCookie1; 188 if (cookie2) *cookie2 = mCookie2; 189 if (cookie3) *cookie3 = mCookie3; 190 } 191 192 private: 193 params* mMainInput; 194 params* mThumbnailInput; 195 encoder_libjpeg_callback_t mCb; 196 bool mCancelEncoding; 197 void* mCookie1; 198 void* mCookie2; 199 void* mCookie3; 200 CameraFrame::FrameType mType; 201 sp<Encoder_libjpeg> mThumb; 202 Semaphore mCancelSem; 203 204 size_t encode(params*); 205 }; 206 207 } 208 209 #endif 210