JPEGEncoder.cc

Go to the documentation of this file.
00001 //
00002 // Copyright 2003 Sony Corporation 
00003 //
00004 // Permission to use, copy, modify, and redistribute this software for
00005 // non-commercial use is hereby granted.
00006 //
00007 // This software is provided "as is" without warranty of any kind,
00008 // either expressed or implied, including but not limited to the
00009 // implied warranties of fitness for a particular purpose.
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];     // Y
00141             *iptr++ = cbline[x];    // Cb
00142             *iptr++ = crline[x];    // Cr
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); // Y_LL
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             // yLH, yHL, yHH : offset binary [0, 255] -> signed int [-128, 127]
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; // ypix11
00183             int b = 2 * (yLL + yLH);       // ypix11 + ypix01
00184             int c = 2 * (yLL + yHL);       // ypix11 + ypix10
00185             int d = 2 * (yLL + yHH);       // ypix11 + ypix00
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); // Y_LL
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             // yLH, yHL, yHH : offset binary [0, 255] -> signed int [-128, 127]
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; // ypix11
00251             int b = 2 * (yLL + yLH);       // ypix11 + ypix01
00252             int c = 2 * (yLL + yHL);       // ypix11 + ypix10
00253             int d = 2 * (yLL + yHH);       // ypix11 + ypix00
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

Generated on Sun Dec 2 23:04:28 2007 for openSDK by  doxygen 1.3.9.1