00001
00002
00003
00004
00005
00006
00007 #include "Platform/GTAssert.h"
00008 #include "JPEGImage.h"
00009
00010 JPEGImage::JPEGImage(const Image& image)
00011 {
00012 *this = image;
00013 }
00014
00015 JPEGImage& JPEGImage::operator=(const Image& src)
00016 {
00017 cameraInfo = src.cameraInfo;
00018 frameNumber = src.frameNumber;
00019
00020 jpeg_compress_struct cInfo;
00021 jpeg_error_mgr jem;
00022 cInfo.err = jpeg_std_error(&jem);
00023 jpeg_create_compress(&cInfo);
00024
00025 if(!cInfo.dest)
00026 cInfo.dest = (jpeg_destination_mgr*)
00027 (*cInfo.mem->alloc_small) ((j_common_ptr) &cInfo,JPOOL_PERMANENT,
00028 sizeof(DestDescriptor));
00029 cInfo.dest->init_destination = onDestInit;
00030 cInfo.dest->empty_output_buffer = onDestEmpty;
00031 cInfo.dest->term_destination = onDestTerm;
00032 ((DestDescriptor*) cInfo.dest)->theObject = this;
00033
00034 cInfo.image_width = cameraInfo.resolutionWidth;
00035 cInfo.image_height = cameraInfo.resolutionHeight * 3;
00036 cInfo.input_components = 1;
00037 cInfo.in_color_space = JCS_GRAYSCALE;
00038 jpeg_set_defaults(&cInfo);
00039 cInfo.dct_method = JDCT_FASTEST;
00040 jpeg_set_quality(&cInfo,75,true);
00041
00042 jpeg_start_compress(&cInfo,true);
00043
00044 while(cInfo.next_scanline < cInfo.image_height)
00045 {
00046 JSAMPROW rowPointer = const_cast<JSAMPROW>(&src.image[cInfo.next_scanline % src.cameraInfo.resolutionHeight]
00047 [cInfo.next_scanline / src.cameraInfo.resolutionHeight][0]);
00048 jpeg_write_scanlines(&cInfo,&rowPointer,1);
00049 }
00050
00051 jpeg_finish_compress(&cInfo);
00052 jpeg_destroy_compress(&cInfo);
00053 return *this;
00054 }
00055
00056 void JPEGImage::toImage(Image& dest) const
00057 {
00058 dest.cameraInfo = cameraInfo;
00059 dest.frameNumber = frameNumber;
00060
00061 jpeg_decompress_struct cInfo;
00062 jpeg_error_mgr jem;
00063 cInfo.err = jpeg_std_error(&jem);
00064
00065 jpeg_create_decompress(&cInfo);
00066
00067 if(!cInfo.src)
00068 cInfo.src = (jpeg_source_mgr *)
00069 (*cInfo.mem->alloc_small)((j_common_ptr) &cInfo,JPOOL_PERMANENT,
00070 sizeof(jpeg_source_mgr));
00071 cInfo.src->init_source = onSrcIgnore;
00072 cInfo.src->fill_input_buffer = onSrcEmpty;
00073 cInfo.src->skip_input_data = onSrcSkip;
00074 cInfo.src->resync_to_restart = jpeg_resync_to_restart;
00075 cInfo.src->term_source = onSrcIgnore;
00076 cInfo.src->bytes_in_buffer = size;
00077 cInfo.src->next_input_byte = (const JOCTET*) image;
00078
00079 jpeg_read_header(&cInfo,true);
00080 jpeg_start_decompress(&cInfo);
00081
00082
00083 while (cInfo.output_scanline < cInfo.output_height)
00084 {
00085 JSAMPROW rowPointer = (unsigned char*) (cInfo.output_height == (unsigned) cameraResolutionHeight_ERS210
00086 ? &dest.image[cInfo.output_scanline][0][0]
00087 : &dest.image[cInfo.output_scanline % dest.cameraInfo.resolutionHeight]
00088 [cInfo.output_scanline / dest.cameraInfo.resolutionHeight][0]);
00089 (void) jpeg_read_scanlines(&cInfo,&rowPointer,1);
00090 }
00091
00092
00093 jpeg_finish_decompress(&cInfo);
00094 jpeg_destroy_decompress(&cInfo);
00095
00096
00097 if(cInfo.output_height == (unsigned) cameraResolutionHeight_ERS210)
00098 for(unsigned i = 0; i < cInfo.output_height; ++i)
00099 for(unsigned c = 2; c > 0; --c)
00100 memmove(&dest.image[i][c][0],
00101 &dest.image[i][0][c * cameraResolutionWidth_ERS210],
00102 cameraResolutionWidth_ERS210);
00103
00104
00105 for(int y = 0; y < dest.cameraInfo.resolutionHeight; ++y)
00106 for(int c = 3; c < 6; ++c)
00107 memset(&dest.image[y][c][0], 128, dest.cameraInfo.resolutionWidth);
00108 }
00109
00110 void JPEGImage::onDestInit(j_compress_ptr cInfo)
00111 {
00112 JPEGImage& image = *((DestDescriptor*) cInfo->dest)->theObject;
00113 cInfo->dest->next_output_byte = (JOCTET*) image.image;
00114 cInfo->dest->free_in_buffer = image.cameraInfo.resolutionWidth * image.cameraInfo.resolutionHeight * 3;
00115 }
00116
00117 int JPEGImage::onDestEmpty(j_compress_ptr)
00118 {
00119 ASSERT(false);
00120 return false;
00121 }
00122
00123 void JPEGImage::onDestTerm(j_compress_ptr cInfo)
00124 {
00125 JPEGImage& image = *((DestDescriptor*) cInfo->dest)->theObject;
00126 image.size = (char*) cInfo->dest->next_output_byte - (char*) image.image;
00127 }
00128
00129 void JPEGImage::onSrcSkip(j_decompress_ptr,long)
00130 {
00131 }
00132
00133 int JPEGImage::onSrcEmpty(j_decompress_ptr)
00134 {
00135 ASSERT(false);
00136 return false;
00137 }
00138
00139 void JPEGImage::onSrcIgnore(j_decompress_ptr)
00140 {
00141 }
00142
00143 Out& operator<<(Out& stream,const JPEGImage& image)
00144 {
00145 ASSERT(image.size);
00146 stream << image.cameraInfo.resolutionWidth << image.cameraInfo.resolutionHeight << image.frameNumber << image.size;
00147 stream.write(&image.image,image.size);
00148 return stream;
00149 }
00150
00151 In& operator>>(In& stream,JPEGImage& image)
00152 {
00153 stream >> image.cameraInfo.resolutionWidth >> image.cameraInfo.resolutionHeight >> image.frameNumber >> image.size;
00154 image.setCameraInfo();
00155 stream.read(&image.image,image.size);
00156 return stream;
00157 }
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227