• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #undef TRUE
34 #undef FALSE
35 
36 }
37 
38 #include "CameraHal.h"
39 
40 #define CANCEL_TIMEOUT 5000000 // 5 seconds
41 
42 namespace Ti {
43 namespace Camera {
44 
45 /**
46  * libjpeg encoder class - uses libjpeg to encode yuv
47  */
48 
49 #define MAX_EXIF_TAGS_SUPPORTED 30
50 typedef void (*encoder_libjpeg_callback_t) (void* main_jpeg,
51                                             void* thumb_jpeg,
52                                             CameraFrame::FrameType type,
53                                             void* cookie1,
54                                             void* cookie2,
55                                             void* cookie3,
56                                             void* cookie4,
57                                             bool canceled);
58 
59 // these have to match strings defined in external/jhead/exif.c
60 static const char TAG_MODEL[] = "Model";
61 static const char TAG_MAKE[] = "Make";
62 static const char TAG_FOCALLENGTH[] = "FocalLength";
63 static const char TAG_DATETIME[] = "DateTime";
64 static const char TAG_IMAGE_WIDTH[] = "ImageWidth";
65 static const char TAG_IMAGE_LENGTH[] = "ImageLength";
66 static const char TAG_GPS_LAT[] = "GPSLatitude";
67 static const char TAG_GPS_LAT_REF[] = "GPSLatitudeRef";
68 static const char TAG_GPS_LONG[] = "GPSLongitude";
69 static const char TAG_GPS_LONG_REF[] = "GPSLongitudeRef";
70 static const char TAG_GPS_ALT[] = "GPSAltitude";
71 static const char TAG_GPS_ALT_REF[] = "GPSAltitudeRef";
72 static const char TAG_GPS_MAP_DATUM[] = "GPSMapDatum";
73 static const char TAG_GPS_PROCESSING_METHOD[] = "GPSProcessingMethod";
74 static const char TAG_GPS_VERSION_ID[] = "GPSVersionID";
75 static const char TAG_GPS_TIMESTAMP[] = "GPSTimeStamp";
76 static const char TAG_GPS_DATESTAMP[] = "GPSDateStamp";
77 static const char TAG_ORIENTATION[] = "Orientation";
78 static const char TAG_FLASH[] = "Flash";
79 static const char TAG_DIGITALZOOMRATIO[] = "DigitalZoomRatio";
80 static const char TAG_EXPOSURETIME[] = "ExposureTime";
81 static const char TAG_APERTURE[] = "ApertureValue";
82 static const char TAG_ISO_EQUIVALENT[] = "ISOSpeedRatings";
83 static const char TAG_WHITEBALANCE[] = "WhiteBalance";
84 static const char TAG_LIGHT_SOURCE[] = "LightSource";
85 static const char TAG_METERING_MODE[] = "MeteringMode";
86 static const char TAG_EXPOSURE_PROGRAM[] = "ExposureProgram";
87 static const char TAG_COLOR_SPACE[] = "ColorSpace";
88 static const char TAG_CPRS_BITS_PER_PIXEL[] = "CompressedBitsPerPixel";
89 static const char TAG_FNUMBER[] = "FNumber";
90 static const char TAG_SHUTTERSPEED[] = "ShutterSpeedValue";
91 static const char TAG_SENSING_METHOD[] = "SensingMethod";
92 static const char TAG_CUSTOM_RENDERED[] = "CustomRendered";
93 
94 class ExifElementsTable {
95     public:
ExifElementsTable()96         ExifElementsTable() :
97            gps_tag_count(0), exif_tag_count(0), position(0),
98            jpeg_opened(false)
99         {
100 #ifdef ANDROID_API_JB_OR_LATER
101             has_datetime_tag = false;
102 #endif
103         }
104         ~ExifElementsTable();
105 
106         status_t insertElement(const char* tag, const char* value);
107         void insertExifToJpeg(unsigned char* jpeg, size_t jpeg_size);
108         status_t insertExifThumbnailImage(const char*, int);
109         void saveJpeg(unsigned char* picture, size_t jpeg_size);
110         static const char* degreesToExifOrientation(unsigned int);
111         static void stringToRational(const char*, unsigned int*, unsigned int*);
112         static bool isAsciiTag(const char* tag);
113     private:
114         ExifElement_t table[MAX_EXIF_TAGS_SUPPORTED];
115         unsigned int gps_tag_count;
116         unsigned int exif_tag_count;
117         unsigned int position;
118         bool jpeg_opened;
119 #ifdef ANDROID_API_JB_OR_LATER
120         bool has_datetime_tag;
121 #endif
122 };
123 
124 class Encoder_libjpeg : public android::Thread {
125     /* public member types and variables */
126     public:
127         struct params {
128             uint8_t* src;
129             int src_size;
130             uint8_t* dst;
131             int dst_size;
132             int quality;
133             int in_width;
134             int in_height;
135             int out_width;
136             int out_height;
137             int right_crop;
138             int start_offset;
139             const char* format;
140             size_t jpeg_size;
141          };
142     /* public member functions */
143     public:
Encoder_libjpeg(params * main_jpeg,params * tn_jpeg,encoder_libjpeg_callback_t cb,CameraFrame::FrameType type,void * cookie1,void * cookie2,void * cookie3,void * cookie4)144         Encoder_libjpeg(params* main_jpeg,
145                         params* tn_jpeg,
146                         encoder_libjpeg_callback_t cb,
147                         CameraFrame::FrameType type,
148                         void* cookie1,
149                         void* cookie2,
150                         void* cookie3, void *cookie4)
151             : android::Thread(false), mMainInput(main_jpeg), mThumbnailInput(tn_jpeg), mCb(cb),
152               mCancelEncoding(false), mCookie1(cookie1), mCookie2(cookie2), mCookie3(cookie3), mCookie4(cookie4),
153               mType(type), mThumb(NULL) {
154             this->incStrong(this);
155             mCancelSem.Create(0);
156         }
157 
~Encoder_libjpeg()158         ~Encoder_libjpeg() {
159             CAMHAL_LOGVB("~Encoder_libjpeg(%p)", this);
160         }
161 
threadLoop()162         virtual bool threadLoop() {
163             size_t size = 0;
164             if (mThumbnailInput) {
165                 // start thread to encode thumbnail
166                 mThumb = new Encoder_libjpeg(mThumbnailInput, NULL, NULL, mType, NULL, NULL, NULL, NULL);
167                 mThumb->run();
168             }
169 
170             // encode our main image
171             size = encode(mMainInput);
172 
173             // signal cancel semaphore incase somebody is waiting
174             mCancelSem.Signal();
175 
176             // check if it is main jpeg thread
177             if(mThumb.get()) {
178                 // wait until tn jpeg thread exits.
179                 mThumb->join();
180                 mThumb.clear();
181                 mThumb = NULL;
182             }
183 
184             if(mCb) {
185                 mCb(mMainInput, mThumbnailInput, mType, mCookie1, mCookie2, mCookie3, mCookie4, mCancelEncoding);
186             }
187 
188             // encoder thread runs, self-destructs, and then exits
189             this->decStrong(this);
190             return false;
191         }
192 
cancel()193         void cancel() {
194            mCancelEncoding = true;
195            if (mThumb.get()) {
196                mThumb->cancel();
197                mCancelSem.WaitTimeout(CANCEL_TIMEOUT);
198            }
199         }
200 
getCookies(void ** cookie1,void ** cookie2,void ** cookie3)201         void getCookies(void **cookie1, void **cookie2, void **cookie3) {
202             if (cookie1) *cookie1 = mCookie1;
203             if (cookie2) *cookie2 = mCookie2;
204             if (cookie3) *cookie3 = mCookie3;
205         }
206 
207     private:
208         params* mMainInput;
209         params* mThumbnailInput;
210         encoder_libjpeg_callback_t mCb;
211         bool mCancelEncoding;
212         void* mCookie1;
213         void* mCookie2;
214         void* mCookie3;
215         void* mCookie4;
216         CameraFrame::FrameType mType;
217         android::sp<Encoder_libjpeg> mThumb;
218         Utils::Semaphore mCancelSem;
219 
220         size_t encode(params*);
221 };
222 
223 } // namespace Camera
224 } // namespace Ti
225 
226 #endif
227