00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include <OPENR/OSyslog.h>
00013 #include <OPENR/OFbkImage.h>
00014 #include "JPEGEncoder.h"
00015 #include "write_jpeg.h"
00016
00017 JPEGEncoder::JPEGEncoder() : ipstackRef(),
00018 pixelInterleavedYCbCr(0),
00019 freeJpegBufList()
00020 {
00021 }
00022
00023 bool
00024 JPEGEncoder::Init(const antStackRef& ipstack)
00025 {
00026 ipstackRef = ipstack;
00027
00028 pixelInterleavedYCbCr = (byte*)malloc(IMAGE_BUFSIZE);
00029 if (pixelInterleavedYCbCr == 0) {
00030 OSYSLOG1((osyslogERROR, "JPEGEncoder::Init() : NO MEMORY"));
00031 return false;
00032 }
00033
00034 for (int i = 0; i < NUM_JPEG_BUF; i++) {
00035
00036 antEnvCreateSharedBufferMsg jpegBufferMsg(JPEG_BUFSIZE);
00037
00038 jpegBufferMsg.Call(ipstackRef, sizeof(jpegBufferMsg));
00039 if (jpegBufferMsg.error != ANT_SUCCESS) {
00040 OSYSLOG1((osyslogERROR, "%s : NO MEMORY antError %d",
00041 "JPEGEncoder::Init()", jpegBufferMsg.error));
00042 return false;
00043 }
00044
00045 jpegBuf[i] = jpegBufferMsg.buffer;
00046 jpegBuf[i].Map();
00047 freeJpegBufList.push_back((byte*)jpegBuf[i].GetAddress());
00048 }
00049
00050 return true;
00051 }
00052
00053 void
00054 JPEGEncoder::FreeJPEG(byte* jpeg)
00055 {
00056 Free(jpeg);
00057 }
00058
00059 bool
00060 JPEGEncoder::GetJPEG(OFbkImageVectorData* imageVec,
00061 OFbkImageLayer layer, bool reconstruction,
00062 int quality, byte** jpeg, int* size)
00063 {
00064 int w, h;
00065 if (reconstruction == true) {
00066 ReconstructAndConvertYCbCr(imageVec, layer,
00067 pixelInterleavedYCbCr, &w, &h);
00068 } else {
00069 ConvertYCbCr(imageVec, layer, pixelInterleavedYCbCr, &w, &h);
00070 }
00071
00072 byte* jbuf = Allocate();
00073 if (jbuf == 0) return false;
00074
00075 int jsize = write_jpeg_mem(pixelInterleavedYCbCr,
00076 w, h, quality, jbuf, JPEG_BUFSIZE);
00077 *jpeg = jbuf;
00078 *size = jsize;
00079
00080 return true;
00081 }
00082
00083 void
00084 JPEGEncoder::Save(OFbkImageVectorData* imageVec,
00085 OFbkImageLayer layer, int quality, char* path)
00086 {
00087 int w, h;
00088 ConvertYCbCr(imageVec, layer, pixelInterleavedYCbCr, &w, &h);
00089
00090 FILE* fp = fopen(path, "w");
00091 if (fp == NULL) {
00092 OSYSLOG1((osyslogERROR, "JPEGEncoder::Save() : can't open %s", path));
00093 return;
00094 }
00095 write_jpeg_file(pixelInterleavedYCbCr, w, h, quality, fp);
00096 fclose(fp);
00097 }
00098
00099 byte*
00100 JPEGEncoder::Allocate()
00101 {
00102 if (freeJpegBufList.size() == 0) return 0;
00103
00104 byte* buf = freeJpegBufList.front();
00105 freeJpegBufList.pop_front();
00106 return buf;
00107 }
00108
00109 void
00110 JPEGEncoder::Free(byte* buf)
00111 {
00112 freeJpegBufList.push_back(buf);
00113 }
00114
00115 void
00116 JPEGEncoder::ConvertYCbCr(OFbkImageVectorData* imageVec,
00117 OFbkImageLayer layer, byte* image,
00118 int* width, int* height)
00119 {
00120 OFbkImageInfo* info = imageVec->GetInfo(layer);
00121 byte* data = imageVec->GetData(layer);
00122
00123 OFbkImage yImg(info, data, ofbkimageBAND_Y);
00124 OFbkImage crImg(info, data, ofbkimageBAND_Cr);
00125 OFbkImage cbImg(info, data, ofbkimageBAND_Cb);
00126
00127 int w = yImg.Width();
00128 int h = yImg.Height();
00129 int skip = yImg.Skip();
00130
00131 byte* iptr = image;
00132
00133 for (int y = 0; y < h; y++) {
00134
00135 byte* yline = yImg.Pointer() + (w + skip) * y;
00136 byte* crline = crImg.Pointer() + (w + skip) * y;
00137 byte* cbline = cbImg.Pointer() + (w + skip) * y;
00138
00139 for (int x = 0; x < w; x++) {
00140 *iptr++ = yline[x];
00141 *iptr++ = cbline[x];
00142 *iptr++ = crline[x];
00143 }
00144
00145 }
00146
00147 *width = w;
00148 *height = h;
00149 }
00150
00151 #ifndef RECONSTRUCT_POINTER_VERSION
00152 void
00153 JPEGEncoder::ReconstructAndConvertYCbCr(OFbkImageVectorData* imageVec,
00154 OFbkImageLayer layer, byte* image,
00155 int* width, int* height)
00156 {
00157 OFbkImageInfo* info = imageVec->GetInfo(layer);
00158 byte* data = imageVec->GetData(layer);
00159
00160 OFbkImage yLLImg(info, data, ofbkimageBAND_Y);
00161 OFbkImage yLHImg(info, data, ofbkimageBAND_Y_LH);
00162 OFbkImage yHLImg(info, data, ofbkimageBAND_Y_HL);
00163 OFbkImage yHHImg(info, data, ofbkimageBAND_Y_HH);
00164
00165 OFbkImage crImg(info, data, ofbkimageBAND_Cr);
00166 OFbkImage cbImg(info, data, ofbkimageBAND_Cb);
00167
00168 int w = yLLImg.Width();
00169 int h = yLLImg.Height();
00170
00171 for (int y = 0; y < h; y++) {
00172
00173 for (int x = 0; x < w; x++) {
00174
00175
00176
00177 int yLL = (int)yLLImg.Pixel(x, y);
00178 int yLH = (int)yLHImg.Pixel(x, y) - 128;
00179 int yHL = (int)yHLImg.Pixel(x, y) - 128;
00180 int yHH = (int)yHHImg.Pixel(x, y) - 128;
00181
00182 int a = yLL + yLH + yHL + yHH;
00183 int b = 2 * (yLL + yLH);
00184 int c = 2 * (yLL + yHL);
00185 int d = 2 * (yLL + yHH);
00186
00187 byte ypix00 = ClipRange(d - a);
00188 byte ypix10 = ClipRange(c - a);
00189 byte ypix01 = ClipRange(b - a);
00190 byte ypix11 = ClipRange(a);
00191
00192 byte cb = cbImg.Pixel(x, y);
00193 byte cr = crImg.Pixel(x, y);
00194
00195 PutYCbCrPixel(image, 2*w, 2*x, 2*y, ypix00, cb, cr);
00196 PutYCbCrPixel(image, 2*w, 2*x+1, 2*y, ypix10, cb, cr);
00197 PutYCbCrPixel(image, 2*w, 2*x, 2*y+1, ypix01, cb, cr);
00198 PutYCbCrPixel(image, 2*w, 2*x+1, 2*y+1, ypix11, cb, cr);
00199 }
00200
00201 }
00202
00203 *width = 2 * w;
00204 *height = 2 * h;
00205 }
00206 #else
00207 void
00208 JPEGEncoder::ReconstructAndConvertYCbCr(OFbkImageVectorData* imageVec,
00209 OFbkImageLayer layer, byte* image,
00210 int* width, int* height)
00211 {
00212 OFbkImageInfo* info = imageVec->GetInfo(layer);
00213 byte* data = imageVec->GetData(layer);
00214
00215 OFbkImage yLLImg(info, data, ofbkimageBAND_Y);
00216 OFbkImage yLHImg(info, data, ofbkimageBAND_Y_LH);
00217 OFbkImage yHLImg(info, data, ofbkimageBAND_Y_HL);
00218 OFbkImage yHHImg(info, data, ofbkimageBAND_Y_HH);
00219
00220 OFbkImage crImg(info, data, ofbkimageBAND_Cr);
00221 OFbkImage cbImg(info, data, ofbkimageBAND_Cb);
00222
00223 byte* yLLPtr = yLLImg.Pointer();
00224 byte* yLHPtr = yLHImg.Pointer();
00225 byte* yHLPtr = yHLImg.Pointer();
00226 byte* yHHPtr = yHHImg.Pointer();
00227
00228 byte* crPtr = crImg.Pointer();
00229 byte* cbPtr = cbImg.Pointer();
00230
00231 int w = yLLImg.Width();
00232 int h = yLLImg.Height();
00233 int skip = yLLImg.Skip();
00234 OSYSDEBUG(("w %d h %d skip %d\n", w, h, skip));
00235
00236 byte* iptr0 = image;
00237 byte* iptr1 = image + 3 * (2 * w);
00238
00239 for (int y = 0; y < h; y++) {
00240
00241 for (int x = 0; x < w; x++) {
00242
00243
00244
00245 int yLL = (int)*yLLPtr++;
00246 int yLH = (int)*yLHPtr++ - 128;
00247 int yHL = (int)*yHLPtr++ - 128;
00248 int yHH = (int)*yHHPtr++ - 128;
00249
00250 int a = yLL + yLH + yHL + yHH;
00251 int b = 2 * (yLL + yLH);
00252 int c = 2 * (yLL + yHL);
00253 int d = 2 * (yLL + yHH);
00254
00255 byte ypix00 = ClipRange(d - a);
00256 byte ypix10 = ClipRange(c - a);
00257 byte ypix01 = ClipRange(b - a);
00258 byte ypix11 = ClipRange(a);
00259
00260 byte cb = *cbPtr++;
00261 byte cr = *crPtr++;
00262
00263 iptr0[0] = ypix00;
00264 iptr0[1] = cb;
00265 iptr0[2] = cr;
00266
00267 iptr0[3] = ypix10;
00268 iptr0[4] = cb;
00269 iptr0[5] = cr;
00270
00271 iptr1[0] = ypix01;
00272 iptr1[1] = cb;
00273 iptr1[2] = cr;
00274
00275 iptr1[3] = ypix11;
00276 iptr1[4] = cb;
00277 iptr1[5] = cr;
00278
00279 iptr0 += 6;
00280 iptr1 += 6;
00281 }
00282
00283 yLLPtr += skip;
00284 yLHPtr += skip;
00285 yHLPtr += skip;
00286 yHHPtr += skip;
00287
00288 cbPtr += skip;
00289 crPtr += skip;
00290
00291 iptr0 += 3 * (2 * w);
00292 iptr1 += 3 * (2 * w);
00293 }
00294
00295 *width = 2 * w;
00296 *height = 2 * h;
00297 }
00298 #endif // RECONSTRUCT_POINTER_VERSION