trunk 20080912
[gitenigma.git] / lib / codecs / picjpeg.cpp
blobab75228a8dd900623a6f70d3e5e50bd38124a79e
1 #ifndef DISABLE_FILE
3 #include <lib/codecs/picjpeg.h>
4 #include <lib/base/eerror.h>
5 #include <lib/base/esize.h>
6 #include <lib/gdi/gpixmap.h>
8 ePictureDecoderJPEG::ePictureDecoderJPEG(eIOBuffer &input): ePictureDecoder(input)
10 // set source!
11 cinfo.err=jpeg_std_error(&jerr);
12 jpeg_create_decompress(&cinfo);
15 ePictureDecoderJPEG::~ePictureDecoderJPEG()
17 jpeg_destroy_decompress(&cinfo);
20 int ePictureDecoderJPEG::decodeMore(int maxscanlines)
22 int decodedscanlines=0;
23 while (decodedscanlines < maxscanlines)
25 int code;
26 switch (state)
28 case stateHeader:
29 code=jpeg_read_header(&cinfo, TRUE);
30 if (code == JPEG_SUSPENDED)
31 return 1024;
32 if (code == JPEG_HEADER_OK)
34 jpeg_calc_output_dimensions(&cinfo);
35 // allocate buffer for decompression
37 row_stride=cinfo.output_width * cinfo.output_components;
38 buffer=(*cinfo.mem->alloc_sarray)((j_common_ptr)&cinfo, JPOOL_IMAGE, row_stride*16, 1);
40 // allocate a gImage for the output
41 if ((cinfo.output_width > 1024) || (cinfo.output_height > 1024))
43 eDebug("Image too big: %d x %d", cinfo.output_width, cinfo.output_height);
44 return -1;
46 int bpp=cinfo.output_components*8;
47 if (bpp == 24)
48 bpp=32;
49 result=new gImage(eSize(cinfo.output_width, cinfo.output_height), bpp);
50 eDebug("JPEG reader: created gImage (%d x %d x %d bpp)", cinfo.output_width, cinfo.output_height, bpp);
51 state=stateStartDecompression;
52 continue;
54 eDebug("jpeg_read_header returned: %d", code);
55 return -1;
56 break;
57 case stateStartDecompression:
58 if (!jpeg_start_decompress(&cinfo))
60 eDebug("jpeg_start_decompress - suspended.");
61 return 1024;
63 state=stateOutput;
64 break;
65 case stateOutput:
67 if (cinfo.output_scanline >= cinfo.output_height)
69 eDebug("finished decompression.");
70 state=stateFinishDecompression;
71 break;
73 int maxlines=maxscanlines - decodedscanlines;
74 if (maxlines > 16)
75 maxlines=16;
76 int d, start=cinfo.output_scanline;
78 d=jpeg_read_scanlines(&cinfo, buffer, maxlines);
79 if (!d)
81 eDebug("need more data..");
82 return 1024; // need more data..
84 if (d < 0)
86 eDebug("fatal error %d while decompressing.", d);
87 if (result)
88 delete result;
89 result=0;
90 return -1;
93 if (cinfo.output_components == 1) // grayscale
95 for (int i=0; i<d; ++i)
96 memcpy(((__u8*)result->data)+result->stride*(start+d), buffer[i], cinfo.output_width);
97 } else if (cinfo.output_components == 3) // true color
99 for (register int i=0; i<d; ++i)
101 __u32 *dst=(__u32*)(((__u8*)result->data)+result->stride*(start+i));
102 JSAMPLE *smp=buffer[i];
104 for (register int x=0; x<result->x; ++x)
105 *dst++=smp[x*3] | (smp[x*3+1]<<8) | (smp[x*3+2]<<16);
108 } else
110 eDebug("unsupported output_components %d", cinfo.output_components);
111 if (result)
112 delete result;
113 result=0;
114 return -1;
116 decodedscanlines+=d;
117 break;
119 case stateFinishDecompression:
121 if (jpeg_finish_decompress(&cinfo))
122 return 1024;
123 state=stateEnd;
124 break;
126 case stateEnd:
128 eDebug("we reached the holy end..");
129 return -1;
133 return 0;
136 #endif //DISABLE_FILE