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 
     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:
     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:
    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 
    142         ~Encoder_libjpeg() {
    143             CAMHAL_LOGVB("~Encoder_libjpeg(%p)", this);
    144         }
    145 
    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 
    178         void cancel() {
    179            mCancelEncoding = true;
    180            if (mThumb.get()) {
    181                mThumb->cancel();
    182                mCancelSem.WaitTimeout(CANCEL_TIMEOUT);
    183            }
    184         }
    185 
    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