00001
00002 #ifdef VCL_NEEDS_PRAGMA_INTERFACE
00003 #pragma implementation
00004 #endif
00005
00006 #include "JPEG_Decompressor.h"
00007
00008 #include <vcl_fstream.h>
00009 #include <vil1/vil1_jpeglib.h>
00010 #include <vpl/vpl_fdopen.h>
00011
00012 struct JPEG_DecompressorPrivates {
00013 jpeg_decompress_struct jinfo;
00014 jpeg_error_mgr jerr;
00015 JSAMPARRAY buffer;
00016 FILE* fileid;
00017 };
00018
00019 JPEG_Decompressor::JPEG_Decompressor(int fd)
00020 {
00021 init(fd);
00022 }
00023
00024
00025 #if defined(VCL_SGI_CC) || defined(VCL_SUNPRO_CC) || (defined(VCL_GCC) && !defined(GNU_LIBSTDCXX_V3))
00026 JPEG_Decompressor::JPEG_Decompressor(vcl_ifstream& f)
00027 {
00028 init(f.rdbuf()->fd());
00029 }
00030 #endif
00031
00032 void JPEG_Decompressor::init(int fd)
00033 {
00034 pd = new JPEG_DecompressorPrivates;
00035
00036
00037 pd->jinfo.err = jpeg_std_error( &pd->jerr);
00038
00039
00040 jpeg_create_decompress( &pd->jinfo);
00041
00042
00043 pd->fileid = vpl_fdopen(fd, "r");
00044 jpeg_stdio_src(&pd->jinfo, pd->fileid);
00045 jpeg_read_header( &pd->jinfo, TRUE);
00046 jpeg_start_decompress( &pd->jinfo);
00047
00048
00049 unsigned long row_stride = pd->jinfo.output_width * pd->jinfo.output_components;
00050
00051
00052 pd->buffer = (*pd->jinfo.mem->alloc_sarray) ((j_common_ptr) &pd->jinfo, JPOOL_IMAGE, row_stride, 1);
00053 }
00054
00055 void JPEG_Decompressor::StartNextJPEG()
00056 {
00057
00058 jpeg_finish_decompress( &pd->jinfo);
00059
00060
00061 (*pd->jinfo.mem->free_pool) ((j_common_ptr) &pd->jinfo, JPOOL_IMAGE);
00062
00063 jpeg_read_header( &pd->jinfo, TRUE);
00064 jpeg_start_decompress( &pd->jinfo);
00065
00066
00067 unsigned long row_stride = pd->jinfo.output_width * pd->jinfo.output_components;
00068
00069
00070 pd->buffer = (*pd->jinfo.mem->alloc_sarray) ((j_common_ptr) &pd->jinfo, JPOOL_IMAGE, row_stride, 1);
00071 }
00072
00073 void* JPEG_Decompressor::GetNextScanLine()
00074 {
00075 if (jpeg_read_scanlines(&pd->jinfo, pd->buffer, 1) != 1)
00076 return 0;
00077 return pd->buffer[0];
00078 }
00079
00080 JPEG_Decompressor::~JPEG_Decompressor()
00081 {
00082
00083 jpeg_abort_decompress( &pd->jinfo);
00084
00085
00086 (*pd->jinfo.mem->free_pool) ((j_common_ptr) &pd->jinfo, JPOOL_IMAGE);
00087
00088 delete pd;
00089 }
00090
00091
00092 int JPEG_Decompressor::height()
00093 {
00094 return pd->jinfo.output_height;
00095 }
00096
00097 int JPEG_Decompressor::width()
00098 {
00099 return pd->jinfo.output_width;
00100 }
00101
00102 int JPEG_Decompressor::GetBitsPixel()
00103 {
00104 return pd->jinfo.output_components;
00105 }
00106
00107
00108
00109
00110
00111 unsigned long jpeg_stdio_ftell(j_decompress_ptr cinfo)
00112 {
00113 typedef struct {
00114 struct jpeg_source_mgr pub;
00115 FILE * infile;
00116 JOCTET * buffer;
00117 bool start_of_file;
00118 } my_source_mgr;
00119
00120 my_source_mgr* src = (my_source_mgr *) (cinfo->src);
00121 if (src->pub.next_input_byte)
00122 return ftell(src->infile) - src->pub.bytes_in_buffer;
00123 else
00124 return 0;
00125 }
00126
00127 unsigned long JPEG_Decompressor::GetFilePosition()
00128 {
00129 return jpeg_stdio_ftell(&pd->jinfo);
00130 }