• 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 
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