00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #ifdef HAVE_CONFIG_H
00031 #include <config.h>
00032 #endif
00033
00034 #include "loaders/SILLYJPGImageLoader.h"
00035
00036 #ifndef SILLY_OPT_INLINE
00037 #define inline
00038 #include "loaders/SILLYJPGImageLoader.icpp"
00039 #undef inline
00040 #endif
00041 #include "loaders/SILLYJPGImageContext.h"
00042
00043
00044 namespace SILLY
00045 {
00046 JPGImageLoader::JPGImageLoader()
00047 : ImageLoader("JPG Image Loader based on jpeg-6b")
00048 {
00049 }
00050
00051 JPGImageLoader::~JPGImageLoader()
00052 {
00053 }
00054
00055
00056 ImageContext* JPGImageLoader::loadHeader(PixelFormat& formatSource, DataSource* data)
00057 {
00058 JPGImageContext* jpg = new JPGImageContext;
00059 jpg->d_source = data;
00060
00061 if (! jpg)
00062 return 0;
00063 if (setjmp(jpg->setjmp_buffer))
00064 {
00065 delete jpg;
00066 return 0;
00067 }
00068 jpeg_read_header(&(jpg->cinfo), TRUE);
00069 if (! jpeg_start_decompress(&(jpg->cinfo)))
00070 {
00071 delete jpg;
00072 return 0;
00073 }
00074
00075
00076 if (jpg->cinfo.output_components != 1 && jpg->cinfo.output_components != 3)
00077 {
00078 printf("JPG unsupported bpp: %d\n", jpg->cinfo.output_components );
00079 jpeg_finish_decompress(& jpg->cinfo);
00080 delete jpg;
00081 return 0;
00082 }
00083 formatSource = PF_RGB;
00084
00085
00086 jpg->setImageSize();
00087 return jpg;
00088 }
00089
00090 bool JPGImageLoader::loadImageData(PixelOrigin origin,
00091 DataSource* data,
00092 ImageContext* context)
00093 {
00094 JPGImageContext* jpg = static_cast<JPGImageContext*>(context);
00095
00096
00097 int row_stride = jpg->getWidth() * jpg->cinfo.output_components;
00098 JSAMPARRAY buffer = (* jpg->cinfo.mem->alloc_sarray)(
00099 (j_common_ptr)(& jpg->cinfo),
00100 JPOOL_IMAGE,
00101 row_stride,
00102 1);
00103 bool finished = true;
00104 size_t height = jpg->getHeight();
00105 size_t width = jpg->getWidth();
00106
00107
00108 while(jpg->cinfo.output_scanline < height)
00109 {
00110 int num_rows = jpeg_read_scanlines(& jpg->cinfo, buffer, 1);
00111 if (num_rows != 1)
00112 {
00113 jpeg_finish_decompress(& jpg->cinfo);
00114 return false;
00115 }
00116 byte red;
00117 byte green;
00118 byte blue;
00119 const byte alpha = 0xff;
00120 byte* in = (byte*)(*buffer);
00121
00122 if (jpg->cinfo.output_components == 1)
00123 {
00124 for(size_t i = 0 ; i < width * num_rows ; ++i)
00125 {
00126 red = *in;
00127 green = *in;
00128 blue = *in;
00129 jpg->setNextPixel(red, green, blue, alpha);
00130 in += 1;
00131 }
00132 }
00133
00134 else
00135 {
00136 for(size_t i = 0 ; i < width * num_rows ; ++i)
00137 {
00138 red = *(in++);
00139 green = *(in++);
00140 blue = *(in++);
00141 jpg->setNextPixel(red, green, blue, alpha);
00142 }
00143 }
00144 }
00145 jpeg_finish_decompress(& jpg->cinfo);
00146
00147 if (origin == PO_BOTTOM_LEFT)
00148 return jpg->flipVertically();
00149 return true;
00150 }
00151
00152
00153
00154
00155
00156
00157 }