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 }