00001
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
00031
00033
00034 #ifndef GROOVX_MEDIA_JPEGPARSER_CC_UTC20050626084018_DEFINED
00035 #define GROOVX_MEDIA_JPEGPARSER_CC_UTC20050626084018_DEFINED
00036
00037 #include "jpegparser.h"
00038
00039 #ifndef HAVE_LIBJPEG
00040
00041 #include "rutz/error.h"
00042
00043 void media::load_jpeg(const char* , media::bmap_data& )
00044 {
00045 throw rutz::error("jpeg image files are not supported in this build",
00046 SRC_POS);
00047 }
00048
00049 #else
00050
00051 #include "geom/vec2.h"
00052
00053 #include "media/bmapdata.h"
00054
00055 #include "rutz/error.h"
00056 #include "rutz/sfmt.h"
00057
00058 #include <csetjmp>
00059 #include <cstdio>
00060 extern "C"
00061 {
00062 #include <jpeglib.h>
00063 }
00064 #include "rutz/trace.h"
00065
00066 namespace
00067 {
00068 struct jpeg_aux
00069 {
00070 FILE* infile;
00071 jmp_buf* jmp_state;
00072 };
00073
00074 void cleanup(jpeg_decompress_struct* cinfo)
00075 {
00076 GVX_TRACE("<jpegparser.cc>::cleanup");
00077
00078 jpeg_aux* aux = static_cast<jpeg_aux*>(cinfo->client_data);
00079 if (aux->infile != 0)
00080 fclose(aux->infile);
00081 jpeg_destroy_decompress(cinfo);
00082 }
00083
00084 void jpeg_error_exit(j_common_ptr cinfo)
00085 {
00086
00087
00088
00089 cinfo->err->output_message(cinfo);
00090
00091 jpeg_aux* aux = static_cast<jpeg_aux*>(cinfo->client_data);
00092 longjmp(*(aux->jmp_state), 1);
00093 }
00094 }
00095
00096 #define SETJMP_TRY(statement) \
00097 do { \
00098 if (setjmp(state) == 0) \
00099 { \
00100 statement; \
00101 } \
00102 else \
00103 { \
00104 throw rutz::error(#statement " failed", SRC_POS); \
00105 } \
00106 } while (0)
00107
00108 void media::load_jpeg(const char* filename, media::bmap_data& data)
00109 {
00110 GVX_TRACE("media::load_jpeg");
00111
00112 if (BITS_IN_JSAMPLE != 8)
00113 {
00114 throw rutz::error("jpeg library must be built for 8 bits-per-sample",
00115 SRC_POS);
00116 }
00117
00118 jmp_buf state;
00119
00120
00121 jpeg_decompress_struct cinfo;
00122 jpeg_error_mgr jerr;
00123
00124 jpeg_aux aux;
00125 aux.infile = 0;
00126 aux.jmp_state = &state;
00127 cinfo.client_data = static_cast<void*>(&aux);
00128
00129 cinfo.err = jpeg_std_error(&jerr);
00130 cinfo.err->error_exit = &jpeg_error_exit;
00131
00132 SETJMP_TRY(jpeg_create_decompress(&cinfo));
00133
00134
00135 aux.infile = fopen(filename, "rb");
00136
00137 if (aux.infile == 0)
00138 {
00139 throw rutz::error(rutz::sfmt("couldn't open '%s' for reading",
00140 filename), SRC_POS);
00141 }
00142
00143
00144 SETJMP_TRY(jpeg_stdio_src(&cinfo, aux.infile));
00145
00146
00147 SETJMP_TRY(jpeg_read_header(&cinfo, TRUE));
00148
00149
00150
00151
00152 SETJMP_TRY(jpeg_start_decompress(&cinfo));
00153
00154
00155
00156
00157
00158
00159
00160 media::bmap_data new_data(geom::vec2<int>(cinfo.output_width,
00161 cinfo.output_height),
00162 cinfo.output_components*BITS_IN_JSAMPLE,
00163 1);
00164
00165 while (cinfo.output_scanline < cinfo.output_height)
00166 {
00167 JSAMPLE* dest = new_data.row_ptr(cinfo.output_scanline);
00168
00169 SETJMP_TRY(jpeg_read_scanlines(&cinfo,
00170 &dest,
00171 1));
00172 }
00173
00174
00175 SETJMP_TRY(jpeg_finish_decompress(&cinfo));
00176
00177
00178 cleanup(&cinfo);
00179
00180 data.swap(new_data);
00181 }
00182
00183 #endif // HAVE_LIBJPEG
00184
00185 static const char __attribute__((used)) vcid_groovx_media_jpegparser_cc_utc20050626084018[] = "$Id: jpegparser.cc 10065 2007-04-12 05:54:56Z rjpeters $ $HeadURL: file:
00186 #endif // !GROOVX_MEDIA_JPEGPARSER_CC_UTC20050626084018_DEFINED