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 namespace android { 34 /** 35 * libjpeg encoder class - uses libjpeg to encode yuv 36 */ 37 38 #define MAX_EXIF_TAGS_SUPPORTED 30 39 typedef void (*encoder_libjpeg_callback_t) (void* main_jpeg, 40 void* thumb_jpeg, 41 CameraFrame::FrameType type, 42 void* cookie1, 43 void* cookie2, 44 void* cookie3); 45 46 static const char TAG_MODEL[] = "Model"; 47 static const char TAG_MAKE[] = "Make"; 48 static const char TAG_FOCALLENGTH[] = "FocalLength"; 49 static const char TAG_DATETIME[] = "DateTime"; 50 static const char TAG_IMAGE_WIDTH[] = "ImageWidth"; 51 static const char TAG_IMAGE_LENGTH[] = "ImageLength"; 52 static const char TAG_GPS_LAT[] = "GPSLatitude"; 53 static const char TAG_GPS_LAT_REF[] = "GPSLatitudeRef"; 54 static const char TAG_GPS_LONG[] = "GPSLongitude"; 55 static const char TAG_GPS_LONG_REF[] = "GPSLongitudeRef"; 56 static const char TAG_GPS_ALT[] = "GPSAltitude"; 57 static const char TAG_GPS_ALT_REF[] = "GPSAltitudeRef"; 58 static const char TAG_GPS_MAP_DATUM[] = "GPSMapDatum"; 59 static const char TAG_GPS_PROCESSING_METHOD[] = "GPSProcessingMethod"; 60 static const char TAG_GPS_VERSION_ID[] = "GPSVersionID"; 61 static const char TAG_GPS_TIMESTAMP[] = "GPSTimeStamp"; 62 static const char TAG_GPS_DATESTAMP[] = "GPSDateStamp"; 63 static const char TAG_ORIENTATION[] = "Orientation"; 64 65 class ExifElementsTable { 66 public: 67 ExifElementsTable() : 68 gps_tag_count(0), exif_tag_count(0), position(0), 69 jpeg_opened(false) { } 70 ~ExifElementsTable(); 71 72 status_t insertElement(const char* tag, const char* value); 73 void insertExifToJpeg(unsigned char* jpeg, size_t jpeg_size); 74 status_t insertExifThumbnailImage(const char*, int); 75 void saveJpeg(unsigned char* picture, size_t jpeg_size); 76 static const char* degreesToExifOrientation(const char*); 77 static void stringToRational(const char*, unsigned int*, unsigned int*); 78 static bool isAsciiTag(const char* tag); 79 private: 80 ExifElement_t table[MAX_EXIF_TAGS_SUPPORTED]; 81 unsigned int gps_tag_count; 82 unsigned int exif_tag_count; 83 unsigned int position; 84 bool jpeg_opened; 85 }; 86 87 class Encoder_libjpeg : public Thread { 88 /* public member types and variables */ 89 public: 90 struct params { 91 uint8_t* src; 92 int src_size; 93 uint8_t* dst; 94 int dst_size; 95 int quality; 96 int in_width; 97 int in_height; 98 int out_width; 99 int out_height; 100 const char* format; 101 size_t jpeg_size; 102 }; 103 /* public member functions */ 104 public: 105 Encoder_libjpeg(params* main_jpeg, 106 params* tn_jpeg, 107 encoder_libjpeg_callback_t cb, 108 CameraFrame::FrameType type, 109 void* cookie1, 110 void* cookie2, 111 void* cookie3) 112 : Thread(false), mMainInput(main_jpeg), mThumbnailInput(tn_jpeg), mCb(cb), 113 mCancelEncoding(false), mCookie1(cookie1), mCookie2(cookie2), mCookie3(cookie3), 114 mType(type), mThumb(NULL) { 115 this->incStrong(this); 116 } 117 118 ~Encoder_libjpeg() { 119 CAMHAL_LOGVB("~Encoder_libjpeg(%p)", this); 120 } 121 122 virtual bool threadLoop() { 123 size_t size = 0; 124 sp<Encoder_libjpeg> tn = NULL; 125 if (mThumbnailInput) { 126 // start thread to encode thumbnail 127 mThumb = new Encoder_libjpeg(mThumbnailInput, NULL, NULL, mType, NULL, NULL, NULL); 128 mThumb->run(); 129 } 130 131 // encode our main image 132 size = encode(mMainInput); 133 134 // check if it is main jpeg thread 135 if(mThumb.get()) { 136 // wait until tn jpeg thread exits. 137 mThumb->join(); 138 mThumb.clear(); 139 mThumb = NULL; 140 } 141 142 if(mCb) { 143 mCb(mMainInput, mThumbnailInput, mType, mCookie1, mCookie2, mCookie3); 144 } 145 146 // encoder thread runs, self-destructs, and then exits 147 this->decStrong(this); 148 return false; 149 } 150 151 void cancel() { 152 if (mThumb.get()) { 153 mThumb->cancel(); 154 } 155 mCancelEncoding = true; 156 } 157 158 private: 159 params* mMainInput; 160 params* mThumbnailInput; 161 encoder_libjpeg_callback_t mCb; 162 bool mCancelEncoding; 163 void* mCookie1; 164 void* mCookie2; 165 void* mCookie3; 166 CameraFrame::FrameType mType; 167 sp<Encoder_libjpeg> mThumb; 168 169 size_t encode(params*); 170 }; 171 172 } 173 174 #endif 175