summaryrefslogtreecommitdiff
path: root/v3/fake-pipeline2/JpegCompressor.h (plain)
blob: 464af4da0791fcab1326774cfe54b8fe46ae60f3
1/*
2 * Copyright (C) 2012 The Android Open Source Project
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/**
19 * This class simulates a hardware JPEG compressor. It receives image buffers
20 * in RGBA_8888 format, processes them in a worker thread, and then pushes them
21 * out to their destination stream.
22 */
23
24#ifndef HW_EMULATOR_CAMERA2_JPEG_H
25#define HW_EMULATOR_CAMERA2_JPEG_H
26
27#include "utils/Thread.h"
28#include "utils/Mutex.h"
29#include "utils/Timers.h"
30#include "Base.h"
31#include <hardware/camera3.h>
32#include <utils/List.h>
33#include <stdio.h>
34
35#include <libexif/exif-entry.h>
36#include <libexif/exif-data.h>
37#include <libexif/exif-ifd.h>
38#include <libexif/exif-loader.h>
39#include <libexif/exif-mem.h>
40
41extern "C" {
42#include <jpeglib.h>
43#include <jhead.h>
44}
45
46namespace android {
47#define MAX_EXIF_TAGS_SUPPORTED 30
48static const char TAG_MODEL[] = "Model";
49static const char TAG_MAKE[] = "Make";
50static const char TAG_FOCALLENGTH[] = "FocalLength";
51static const char TAG_DATETIME[] = "DateTime";
52static const char TAG_IMAGE_WIDTH[] = "ImageWidth";
53static const char TAG_IMAGE_LENGTH[] = "ImageLength";
54static const char TAG_GPS_LAT[] = "GPSLatitude";
55static const char TAG_GPS_LAT_REF[] = "GPSLatitudeRef";
56static const char TAG_GPS_LONG[] = "GPSLongitude";
57static const char TAG_GPS_LONG_REF[] = "GPSLongitudeRef";
58static const char TAG_GPS_ALT[] = "GPSAltitude";
59static const char TAG_GPS_ALT_REF[] = "GPSAltitudeRef";
60static const char TAG_GPS_MAP_DATUM[] = "GPSMapDatum";
61static const char TAG_GPS_PROCESSING_METHOD[] = "GPSProcessingMethod";
62static const char TAG_GPS_VERSION_ID[] = "GPSVersionID";
63static const char TAG_GPS_TIMESTAMP[] = "GPSTimeStamp";
64static const char TAG_GPS_DATESTAMP[] = "GPSDateStamp";
65static const char TAG_ORIENTATION[] = "Orientation";
66
67static const char TAG_EXPOSURETIME[] = "ExposureTime";
68static const char TAG_APERTURE[] = "ApertureValue";
69static const char TAG_FLASH[] = "Flash";
70static const char TAG_WHITEBALANCE[] = "WhiteBalance";
71static const char TAG_ISO_EQUIVALENT[] = "ISOSpeedRatings";
72static const char TAG_DATETIME_DIGITIZED[] = "DateTimeDigitized";
73static const char TAG_SUBSEC_TIME[] = "SubSecTime";
74static const char TAG_SUBSEC_TIME_ORIG[] = "SubSecTimeOriginal";
75static const char TAG_SUBSEC_TIME_DIG[] = "SubSecTimeDigitized";
76
77struct CaptureRequest {
78 uint32_t frameNumber;
79 camera3_stream_buffer *buf;
80 Buffers *sensorBuffers;
81 bool mNeedThumbnail;
82};
83
84typedef struct _exif_buffer {
85 unsigned char *data;
86 unsigned int size;
87} exif_buffer;
88
89class ExifElementsTable {
90 public:
91 ExifElementsTable() :
92 gps_tag_count(0), exif_tag_count(0), position(0),
93 jpeg_opened(false) { }
94 ~ExifElementsTable();
95 status_t insertElement(const char* tag, const char* value);
96 void insertExifToJpeg(unsigned char* jpeg, size_t jpeg_size);
97 status_t insertExifThumbnailImage(const char*, int);
98 void saveJpeg(unsigned char* picture, size_t jpeg_size);
99 static const char* degreesToExifOrientation(const char*);
100 static void stringToRational(const char*, unsigned int*, unsigned int*);
101 static bool isAsciiTag(const char* tag);
102 private:
103 ExifElement_t table[MAX_EXIF_TAGS_SUPPORTED];
104 unsigned int gps_tag_count;
105 unsigned int exif_tag_count;
106 unsigned int position;
107 bool jpeg_opened;
108};
109
110class JpegCompressor: private Thread, public virtual RefBase {
111 public:
112
113 JpegCompressor();
114 ~JpegCompressor();
115
116 struct JpegListener {
117 // Called when JPEG compression has finished, or encountered an error
118 virtual void onJpegDone(const StreamBuffer &jpegBuffer,
119 bool success, CaptureRequest &r) = 0;
120 // Called when the input buffer for JPEG is not needed any more,
121 // if the buffer came from the framework.
122 virtual void onJpegInputDone(const StreamBuffer &inputBuffer) = 0;
123 virtual ~JpegListener();
124 };
125
126 // Start compressing COMPRESSED format buffers; JpegCompressor takes
127 // ownership of the Buffers vector.
128 status_t start();
129 status_t setlistener(JpegListener *listener);
130 void queueRequest(CaptureRequest &r);
131
132 // Compress and block until buffer is complete.
133 status_t compressSynchronous(Buffers *buffers);
134
135 status_t cancel();
136
137 bool isBusy();
138 bool isStreamInUse(uint32_t id);
139
140 bool waitForDone(nsecs_t timeout);
141 ssize_t GetMaxJpegBufferSize();
142 void SetMaxJpegBufferSize(ssize_t size);
143 void SetExifInfo(struct ExifInfo info);
144 int GenExif(ExifElementsTable* exiftable);
145 status_t Create_Exif_Use_Libjpeg();
146 status_t Create_Exif_Use_Libexif();
147 exif_buffer *get_exif_buffer();
148 void exif_entry_set_string (ExifData * pEdata, ExifIfd eEifd, ExifTag eEtag, const char *s);
149 void exif_entry_set_short (ExifData * pEdata, ExifIfd eEifd, ExifTag eEtag, ExifShort n);
150 void exif_entry_set_long (ExifData * pEdata, ExifIfd eEifd, ExifTag eEtag, ExifLong n);
151 void exif_entry_set_rational (ExifData * pEdata, ExifIfd eEifd, ExifTag eEtag, ExifRational r);
152 void exif_entry_set_undefined (ExifData * pEdata, ExifIfd eEifd, ExifTag eEtag, exif_buffer * buf);
153 ExifEntry *init_tag(ExifData *exif, ExifIfd ifd, ExifTag tag);
154 ExifEntry *create_tag(ExifData *exif, ExifIfd ifd, ExifTag tag, size_t len);
155 void exif_entry_set_gps_coord(ExifData * pEdata, ExifTag eEtag,
156 ExifRational r1, ExifRational r2, ExifRational r3);
157 void exif_entry_set_gps_altitude(ExifData * pEdata, ExifTag eEtag, ExifRational r1);
158 void exif_entry_set_gps_coord_ref(ExifData * pEdata, ExifTag eEtag, const char *s);
159 void exif_entry_set_gps_altitude_ref(ExifData * pEdata, ExifTag eEtag, ExifByte n);
160
161 // TODO: Measure this
162 static const size_t kMaxJpegSize = 8000000;
163 ssize_t mMaxbufsize;
164
165 private:
166 Mutex mBusyMutex;
167 bool mIsBusy;
168 Condition mDone;
169 bool mSynchronous;
170
171 Mutex mMutex;
172
173 List<CaptureRequest*> mInJpegRequestQueue;
174 Condition mInJpegRequestSignal;
175 camera3_stream_buffer *tempHalbuffers;
176 Buffers *tempBuffers;
177 CaptureRequest mJpegRequest;
178 bool mExitJpegThread;
179 bool mNeedexif;
180 int mMainJpegSize, mThumbJpegSize;
181 uint8_t *mSrcThumbBuffer;
182 uint8_t *mDstThumbBuffer;
183 Buffers *mBuffers;
184 int mPendingrequest;
185 JpegListener *mListener;
186 struct ExifInfo mInfo;
187 StreamBuffer mJpegBuffer, mAuxBuffer;
188 bool mFoundJpeg, mFoundAux;
189 jpeg_compress_struct mCInfo;
190
191 struct JpegError : public jpeg_error_mgr {
192 JpegCompressor *parent;
193 };
194 j_common_ptr mJpegErrorInfo;
195
196 struct JpegDestination : public jpeg_destination_mgr {
197 JpegCompressor *parent;
198 };
199
200 bool checkError(const char *msg);
201 status_t compress();
202
203 status_t thumbcompress();
204 void cleanUp();
205
206 /**
207 * Inherited Thread virtual overrides
208 */
209 private:
210 virtual status_t readyToRun();
211 virtual bool threadLoop();
212};
213
214} // namespace android
215
216#endif
217