Home | History | Annotate | Download | only in inc
      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:
     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:
    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 
    158         ~Encoder_libjpeg() {
    159             CAMHAL_LOGVB("~Encoder_libjpeg(%p)", this);
    160         }
    161 
    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 
    193         void cancel() {
    194            mCancelEncoding = true;
    195            if (mThumb.get()) {
    196                mThumb->cancel();
    197                mCancelSem.WaitTimeout(CANCEL_TIMEOUT);
    198            }
    199         }
    200 
    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