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