00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include <stdio.h>
00025 #include <stdlib.h>
00026 #include <string.h>
00027 #include <jpeglib.h>
00028
00029 #define __IMAGE_MODULE
00030
00031 #include "Bases.h"
00032 #include "Module.h"
00033 #include "Memory.h"
00034 #include "Common.h"
00035 #include "debug.h"
00036 #include "macros.h"
00037
00038 #include "images/image_Jpeg.h"
00039
00040
00041 #ifdef CYGWIN
00042 #ifndef UNIX
00043 #include <sys/reent.h>
00044 struct _reent *_impure_ptr __ATTRIBUTE_IMPURE_PTR__;
00045 int __errno;
00046 #endif
00047 #endif
00048
00049 typedef struct jpeg_CustomData_s
00050 {
00051 Image_t *img;
00052 int fp;
00053 struct jpeg_decompress_struct cinfo;
00054 struct jpeg_error_mgr jerr;
00055 } jpeg_CustomData_t;
00056
00057
00058 static char *jpeg_name="jpeg";
00059
00060
00061
00062
00063 typedef struct
00064 {
00065 struct jpeg_source_mgr pub;
00066 jpeg_CustomData_t *cdata;
00067 boolean start_of_file;
00068 } my_source_mgr;
00069
00070
00071 typedef my_source_mgr * my_src_ptr;
00072
00073
00074 static bases_Modules_t *api;
00075 VERSION("Jpeg.image_mod",1,0,"Gergely Gati","g.gati@freemail.hu");
00076
00077
00078 METHODDEF(void)
00079 my_init_source (j_decompress_ptr cinfo)
00080 {
00081 my_src_ptr src = (my_src_ptr) cinfo->src;
00082 src->start_of_file = TRUE;
00083 src->cdata->fp=0;
00084 }
00085
00086 METHODDEF(boolean)
00087 my_fill_input_buffer (j_decompress_ptr cinfo)
00088 {
00089 my_src_ptr src = (my_src_ptr) cinfo->src;
00090
00091 src->pub.next_input_byte = &src->cdata->img->iim.data[src->cdata->fp];
00092 src->pub.bytes_in_buffer = min(src->cdata->img->iim.data_size-src->cdata->fp,4096);
00093 src->start_of_file = FALSE;
00094 src->cdata->fp+=src->pub.bytes_in_buffer;
00095
00096 return TRUE;
00097 }
00098
00099 METHODDEF(void)
00100 my_skip_input_data (j_decompress_ptr cinfo, long num_bytes)
00101 {
00102 my_src_ptr src = (my_src_ptr) cinfo->src;
00103
00104 if (num_bytes > 0)
00105 {
00106 while (num_bytes > (long) src->pub.bytes_in_buffer)
00107 {
00108 num_bytes -= (long) src->pub.bytes_in_buffer;
00109 (void) my_fill_input_buffer(cinfo);
00110 }
00111 src->pub.next_input_byte += (size_t) num_bytes;
00112 src->pub.bytes_in_buffer -= (size_t) num_bytes;
00113 }
00114 }
00115
00116 METHODDEF(void)
00117 my_term_source (j_decompress_ptr cinfo)
00118 {
00119 }
00120
00121 GLOBAL(void)
00122 jpeg_my_stdio_src (j_decompress_ptr cinfo, jpeg_CustomData_t *cdata)
00123 {
00124 my_src_ptr src;
00125
00126 if (cinfo->src == NULL)
00127 {
00128 cinfo->src = (struct jpeg_source_mgr *)(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, sizeof(my_source_mgr));
00129 src = (my_src_ptr) cinfo->src;
00130 }
00131
00132 src = (my_src_ptr) cinfo->src;
00133 src->pub.init_source = my_init_source;
00134 src->pub.fill_input_buffer = my_fill_input_buffer;
00135 src->pub.skip_input_data = my_skip_input_data;
00136 src->pub.resync_to_restart = jpeg_resync_to_restart;
00137 src->pub.term_source = my_term_source;
00138 src->cdata = cdata;
00139 src->pub.bytes_in_buffer = 0;
00140 src->pub.next_input_byte = NULL;
00141 }
00142
00143
00144
00145
00146
00147 static void my_error_exit(j_common_ptr cinfo)
00148 {
00149 printf("%s\n",__FUNCTION__);
00150 exit(0);
00151 }
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161 static int jpeg_ImgInit(Image_t *img, void (*update)(void *),void *userdata)
00162 {
00163 int ret=-1;
00164 jpeg_CustomData_t *cdata;
00165
00166 debug_Begin();
00167
00168 if(img!=NULL)
00169 {
00170 if(img->format==NULL||strcmp(img->format,jpeg_name)==0)
00171 {
00172 if(img->iim.data[6]=='J'&&img->iim.data[7]=='F'&&img->iim.data[8]=='I'&&img->iim.data[9]=='F')
00173 {
00174 if(img->format==NULL) img->format=jpeg_name;
00175 if(NULL!=(cdata=mem_malloc(sizeof(jpeg_CustomData_t))))
00176 {
00177 img->formatdata=cdata;
00178 cdata->img=img;
00179 cdata->fp=0;
00180 cdata->cinfo.err=jpeg_std_error(&cdata->jerr);
00181 cdata->jerr.error_exit=my_error_exit;
00182 jpeg_create_decompress(&cdata->cinfo);
00183 jpeg_my_stdio_src(&cdata->cinfo,cdata);
00184 jpeg_read_header(&cdata->cinfo,TRUE);
00185 img->minwidth=img->maxwidth=cdata->cinfo.image_width;
00186 img->minheight=img->maxheight=cdata->cinfo.image_height;
00187 jpeg_destroy_decompress(&cdata->cinfo);
00188 ret=0;
00189 }
00190 }
00191 }
00192 }
00193
00194 debug_End();
00195
00196 return(ret);
00197 }
00198
00199
00200 static void jpeg_ImgCleanUp(Image_t *img)
00201 {
00202 jpeg_CustomData_t *cdata;
00203
00204 debug_Begin();
00205
00206 if(img!=NULL)
00207 {
00208 cdata=(jpeg_CustomData_t *)img->formatdata;
00209 if(cdata!=NULL) mem_free(cdata);
00210 }
00211
00212 debug_End();
00213 }
00214
00215
00216
00217
00218
00219
00220 static int jpeg_ImgRender(Image_t *img, u8 *dest, int destsize, int width, int height)
00221 {
00222 jpeg_CustomData_t *cdata;
00223 JSAMPARRAY row_pointers;
00224 int i;
00225
00226 debug_Begin();
00227
00228 if(img!=NULL&&img->formatdata!=NULL&&dest!=NULL&&destsize>=(width*height*4)&&width==img->minwidth&&height==img->minheight)
00229 {
00230 cdata=(jpeg_CustomData_t *)img->formatdata;
00231
00232 cdata->fp=0;
00233 jpeg_create_decompress(&cdata->cinfo);
00234 jpeg_my_stdio_src(&cdata->cinfo,cdata);
00235 jpeg_read_header(&cdata->cinfo,TRUE);
00236
00237
00238 jpeg_start_decompress(&cdata->cinfo);
00239 if(NULL!=(row_pointers=mem_malloc(height*sizeof(JSAMPROW))))
00240 {
00241 for(i=0;i<height;i++) row_pointers[i]=&dest[width*(i*4)];
00242 for(i=0;cdata->cinfo.output_scanline < cdata->cinfo.output_height;i++)
00243 {
00244 jpeg_read_scanlines(&cdata->cinfo,&row_pointers[i],1);
00245 }
00246 mem_free(row_pointers);
00247 }
00248 jpeg_finish_decompress(&cdata->cinfo);
00249 jpeg_destroy_decompress(&cdata->cinfo);
00250 }
00251
00252 debug_End();
00253
00254 return(0);
00255 }
00256
00257
00258 static int jpeg_PutImage(Image_t *img, u32 window, Rect_t *rect)
00259 {
00260 Vector_t buff;
00261
00262 debug_Begin();
00263
00264 buff.size=(rect->width*rect->height*4)+1;
00265 if(NULL!=(buff.data=mem_malloc(buff.size)))
00266 {
00267 if(0==(jpeg_ImgRender(img,buff.data,buff.size,rect->width,rect->height)))
00268 {
00269 api->glw_Call(GLW_PUTIMAGE,TAG_GLW_WINDOW,window,TAG_GLW_PIXELS,&buff,TAG_GLW_CLIPRECT,rect,TAG_GLW_LEFT,rect->left,TAG_GLW_TOP,rect->top,TAG_GLW_WIDTH,rect->width,TAG_GLW_HEIGHT,rect->height,TAG_DONE);
00270 }
00271 mem_free(buff.data);
00272 }
00273
00274 debug_End();
00275
00276 return(0);
00277 }
00278
00279
00280 static void jpeg_CleanUp(void)
00281 {
00282 debug_Begin();
00283 debug_End();
00284 }
00285
00286
00287 static int jpeg_Init(u32 module)
00288 {
00289 int ret=-1;
00290
00291 debug_Begin();
00292
00293 ret=api->img_Call(IMG_REGISTERFORMATCODE,
00294 TAG_IMG_NAME,(u32)"jpeg",
00295 TAG_IMG_IMG_INIT,(u32)jpeg_ImgInit,
00296 TAG_IMG_IMG_RENDER,(u32)jpeg_ImgRender,
00297 TAG_IMG_IMG_PUTIMAGE,(u32)jpeg_PutImage,
00298 TAG_IMG_IMG_CLEAN,(u32)jpeg_ImgCleanUp,
00299 TAG_IMG_CLEANUP,(u32)jpeg_CleanUp,
00300 TAG_IMG_MODULE,module,
00301 TAG_DONE);
00302
00303 debug_Begin();
00304
00305 return(ret);
00306 }
00307
00308 EXPORT int module_Init(u32 module, bases_Modules_t *bases)
00309 {
00310 api=bases;
00311 return(jpeg_Init(module));
00312 }