1 #include <lib/gdi/picload.h>
3 #include <lib/python/python.h>
14 //#include "transupp.h"
18 unsigned char *pic_buffer=NULL;
20 static unsigned char *simple_resize(unsigned char * orgin, int ox, int oy, int dx, int dy)
22 unsigned char *cr, *p, *l;
24 cr = new unsigned char[dx * dy * 3];
27 printf("[RESIZE] Error: malloc\n");
32 for (j = 0; j < dy; j++,l += dx * 3)
34 p = orgin + (j * oy / dy * ox * 3);
35 for (i = 0, k = 0; i < dx; i++, k += 3)
47 static unsigned char *color_resize(unsigned char * orgin, int ox, int oy, int dx, int dy)
49 unsigned char *cr, *p, *q;
50 int i, j, k, l, xa, xb, ya, yb;
52 cr = new unsigned char[dx * dy * 3];
55 printf("[RESIZE] Error: malloc\n");
60 for (j = 0; j < dy; j++)
62 for (i = 0; i < dx; i++, p += 3)
66 xb = (i + 1) * ox / dx;
69 yb = (j + 1) * oy / dy;
72 for (l = ya, r = 0, g = 0, b = 0, sq = 0; l <= yb; l++)
74 q = orgin + ((l * ox + xa) * 3);
75 for (k = xa; k <= xb; k++, q += 3, sq++)
77 r += q[0]; g += q[1]; b += q[2];
80 p[0] = r / sq; p[1] = g / sq; p[2] = b / sq;
87 //-------------------------------------------------------------------
89 struct r_jpeg_error_mgr
91 struct jpeg_error_mgr pub;
95 void jpeg_cb_error_exit(j_common_ptr cinfo)
97 struct r_jpeg_error_mgr *mptr;
98 mptr = (struct r_jpeg_error_mgr *) cinfo->err;
99 (*cinfo->err->output_message) (cinfo);
100 longjmp(mptr->envbuffer, 1);
103 static int jpeg_save(unsigned char *image_buffer, const char * filename, int quality, int image_height, int image_width)
105 struct jpeg_compress_struct cinfo;
106 struct jpeg_error_mgr jerr;
107 FILE * outfile; /* target file */
108 JSAMPROW row_pointer[1];/* pointer to JSAMPLE row[s] */
109 int row_stride; /* physical row width in image buffer */
111 cinfo.err = jpeg_std_error(&jerr);
112 jpeg_create_compress(&cinfo);
114 if ((outfile = fopen(filename, "wb")) == NULL)
116 eDebug("[JPEG] can't open %s", filename);
119 jpeg_stdio_dest(&cinfo, outfile);
121 cinfo.image_width = image_width;
122 cinfo.image_height = image_height;
123 cinfo.input_components = 3;
124 cinfo.in_color_space = JCS_RGB;
125 jpeg_set_defaults(&cinfo);
126 jpeg_set_quality(&cinfo, quality, TRUE );
127 jpeg_start_compress(&cinfo, TRUE);
128 row_stride = image_width * 3;
129 while (cinfo.next_scanline < cinfo.image_height)
131 row_pointer[0] = & image_buffer[cinfo.next_scanline * row_stride];
132 (void) jpeg_write_scanlines(&cinfo, row_pointer, 1);
134 jpeg_finish_compress(&cinfo);
136 jpeg_destroy_compress(&cinfo);
141 static int jpeg_load(const char *filename, int *x, int *y)
143 struct jpeg_decompress_struct cinfo;
144 struct jpeg_decompress_struct *ciptr = &cinfo;
145 struct r_jpeg_error_mgr emgr;
148 if (!(fh = fopen(filename, "rb")))
151 ciptr->err = jpeg_std_error(&emgr.pub);
152 emgr.pub.error_exit = jpeg_cb_error_exit;
153 if (setjmp(emgr.envbuffer) == 1)
155 jpeg_destroy_decompress(ciptr);
160 jpeg_create_decompress(ciptr);
161 jpeg_stdio_src(ciptr, fh);
162 jpeg_read_header(ciptr, TRUE);
163 ciptr->out_color_space = JCS_RGB;
164 ciptr->scale_denom = 1;
166 jpeg_start_decompress(ciptr);
168 *x=ciptr->output_width;
169 *y=ciptr->output_height;
171 if(ciptr->output_components == 3)
173 JSAMPLE *lb = (JSAMPLE *)(*ciptr->mem->alloc_small)((j_common_ptr) ciptr, JPOOL_PERMANENT, ciptr->output_width * ciptr->output_components);
174 pic_buffer = new unsigned char[ciptr->output_height * ciptr->output_width * ciptr->output_components];
175 unsigned char *bp = pic_buffer;
177 while (ciptr->output_scanline < ciptr->output_height)
179 jpeg_read_scanlines(ciptr, &lb, 1);
180 memcpy(bp, lb, ciptr->output_width * ciptr->output_components);
181 bp += ciptr->output_width * ciptr->output_components;
184 jpeg_finish_decompress(ciptr);
185 jpeg_destroy_decompress(ciptr);
190 //---------------------------------------------------------------------------------------------
192 #define BMP_TORASTER_OFFSET 10
193 #define BMP_SIZE_OFFSET 18
194 #define BMP_BPP_OFFSET 28
195 #define BMP_RLE_OFFSET 30
196 #define BMP_COLOR_OFFSET 54
198 #define fill4B(a) ((4 - ((a) % 4 )) & 0x03)
200 static int bmp_load(const char *filename, int *x, int *y)
202 unsigned char buff[4];
204 int fd = open(filename, O_RDONLY);
205 if (fd == -1) return 0;
206 if (lseek(fd, BMP_SIZE_OFFSET, SEEK_SET) == -1) return 0;
208 *x = buff[0] + (buff[1] << 8) + (buff[2] << 16) + (buff[3] << 24);
210 *y = buff[0] + (buff[1] << 8) + (buff[2] << 16) + (buff[3] << 24);
211 if (lseek(fd, BMP_TORASTER_OFFSET, SEEK_SET) == -1) return 0;
213 int raster = buff[0] + (buff[1] << 8) + (buff[2] << 16) + (buff[3] << 24);
214 if (lseek(fd, BMP_BPP_OFFSET, SEEK_SET) == -1) return 0;
216 int bpp = buff[0] + (buff[1] << 8);
218 //printf("x=%d, y=%d,bpp=%d\n",*x, *y, bpp);
219 pic_buffer = new unsigned char[(*x) * (*y) * 3];
220 unsigned char *wr_buffer = pic_buffer + (*x) * ((*y) - 1) * 3;
226 int skip = fill4B((*x) * 3);
227 lseek(fd, raster, SEEK_SET);
229 for (int i = 0; i < (*y); i++)
231 read(fd, wr_buffer, (*x) * 3);
232 for (int j = 0; j < (*x) * 3 ; j = j + 3)
235 wr_buffer[j] = wr_buffer[j + 2];
236 wr_buffer[j + 2] = c;
239 read(fd, buff, skip);
240 wr_buffer -= (*x) * 3;
252 //---------------------------------------------------------------------------------------------
254 static int png_load(const char *filename, int *x, int *y)
256 static const png_color_16 my_background = {0, 0, 0, 0, 0};
260 png_uint_32 width, height;
262 int bit_depth, color_type, interlace_type;
263 int number_passes, pass;
267 if (!(fh = fopen(filename, "rb"))) return 0;
269 png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
272 info_ptr = png_create_info_struct(png_ptr);
273 if (info_ptr == NULL)
275 png_destroy_read_struct(&png_ptr, (png_infopp)NULL, (png_infopp)NULL);
280 if (setjmp(png_ptr->jmpbuf))
282 png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL);
287 png_init_io(png_ptr, fh);
289 png_read_info(png_ptr, info_ptr);
290 png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, &interlace_type, NULL, NULL);
292 if (color_type == PNG_COLOR_TYPE_PALETTE)
294 png_set_palette_to_rgb(png_ptr);
295 png_set_background(png_ptr, (png_color_16 *)&my_background, PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0);
298 if (color_type == PNG_COLOR_TYPE_GRAY || color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
300 png_set_gray_to_rgb(png_ptr);
301 png_set_background(png_ptr, (png_color_16 *)&my_background, PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0);
304 if (color_type & PNG_COLOR_MASK_ALPHA)
305 png_set_strip_alpha(png_ptr);
307 if (bit_depth < 8) png_set_packing(png_ptr);
308 if (bit_depth == 16) png_set_strip_16(png_ptr);
310 number_passes = png_set_interlace_handling(png_ptr);
311 png_read_update_info(png_ptr, info_ptr);
313 if (width * 3 != png_get_rowbytes(png_ptr, info_ptr))
315 eDebug("[PNG] Error processing");
319 pic_buffer = new unsigned char[width * height * 3];
323 for(pass = 0; pass < number_passes; pass++)
325 fbptr = (png_byte *)pic_buffer;
326 for (i = 0; i < height; i++, fbptr += width * 3)
327 png_read_row(png_ptr, fbptr, NULL);
329 png_read_end(png_ptr, info_ptr);
330 png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL);
335 //---------------------------------------------------------------------------------------------
337 PyObject *getExif(const char *filename)
341 if(exif.DecodeExif(filename))
343 if(exif.m_exifinfo->IsExif)
347 list = PyList_New(22);
348 PyList_SET_ITEM(list, pos++, PyString_FromString(exif.m_exifinfo->Version));
349 PyList_SET_ITEM(list, pos++, PyString_FromString(exif.m_exifinfo->CameraMake));
350 PyList_SET_ITEM(list, pos++, PyString_FromString(exif.m_exifinfo->CameraModel));
351 PyList_SET_ITEM(list, pos++, PyString_FromString(exif.m_exifinfo->DateTime));
352 PyList_SET_ITEM(list, pos++, PyString_FromString(exif.m_exifinfo->Comments));
353 PyList_SET_ITEM(list, pos++, PyString_FromFormat("%d x %d", exif.m_exifinfo->Width, exif.m_exifinfo->Height));
354 PyList_SET_ITEM(list, pos++, PyString_FromString(exif.m_exifinfo->Orientation));
355 PyList_SET_ITEM(list, pos++, PyString_FromString(exif.m_exifinfo->MeteringMode));
356 PyList_SET_ITEM(list, pos++, PyString_FromString(exif.m_exifinfo->ExposureProgram));
357 PyList_SET_ITEM(list, pos++, PyString_FromString(exif.m_exifinfo->LightSource));
358 PyList_SET_ITEM(list, pos++, PyString_FromString(exif.m_exifinfo->FlashUsed));
359 PyList_SET_ITEM(list, pos++, PyString_FromFormat("%d", exif.m_exifinfo->CompressionLevel));
360 PyList_SET_ITEM(list, pos++, PyString_FromFormat("%d", exif.m_exifinfo->ISOequivalent));
361 sprintf(tmp, "%.2f", exif.m_exifinfo->Xresolution);
362 PyList_SET_ITEM(list, pos++, PyString_FromString(tmp));
363 sprintf(tmp, "%.2f", exif.m_exifinfo->Yresolution);
364 PyList_SET_ITEM(list, pos++, PyString_FromString(tmp));
365 PyList_SET_ITEM(list, pos++, PyString_FromString(exif.m_exifinfo->ResolutionUnit));
366 sprintf(tmp, "%.2f", exif.m_exifinfo->Brightness);
367 PyList_SET_ITEM(list, pos++, PyString_FromString(tmp));
368 sprintf(tmp, "%.5f sec.", exif.m_exifinfo->ExposureTime);
369 PyList_SET_ITEM(list, pos++, PyString_FromString(tmp));
370 sprintf(tmp, "%.5f", exif.m_exifinfo->ExposureBias);
371 PyList_SET_ITEM(list, pos++, PyString_FromString(tmp));
372 sprintf(tmp, "%.5f", exif.m_exifinfo->Distance);
373 PyList_SET_ITEM(list, pos++, PyString_FromString(tmp));
374 sprintf(tmp, "%.5f", exif.m_exifinfo->CCDWidth);
375 PyList_SET_ITEM(list, pos++, PyString_FromString(tmp));
376 sprintf(tmp, "%.2f", exif.m_exifinfo->ApertureFNumber);
377 PyList_SET_ITEM(list, pos++, PyString_FromString(tmp));
381 list = PyList_New(1);
382 PyList_SET_ITEM(list, 0, PyString_FromString(exif.m_szLastError));
388 list = PyList_New(1);
389 PyList_SET_ITEM(list, 0, PyString_FromString(exif.m_szLastError));
392 return list ? (PyObject*)list : (PyObject*)PyList_New(0);
395 //---------------------------------------------------------------------------------------------
397 int loadPic(ePtr<gPixmap> &result, std::string filename, int w, int h, int aspect, int resize_mode, int rotate, int background, std::string cachefile)
400 int ox=0, oy=0, imx, imy;
404 if(cachefile.length())
407 if(jpeg_load(cachefile.c_str(), &ox, &oy))
408 eDebug("[CACHEPIC] x-size=%d, y-size=%d", ox, oy);
413 unsigned int pos = filename.find_last_of(".");
414 if (pos == std::string::npos)
415 pos = filename.length() - 1;
416 std::string ext = filename.substr(pos);
417 std::transform(ext.begin(), ext.end(), ext.begin(), (int(*)(int)) toupper);
418 if(ext == ".JPEG" || ext == ".JPG")
419 jpeg_load(filename.c_str(), &ox, &oy);
420 else if(ext == ".BMP")
421 bmp_load(filename.c_str(), &ox, &oy);
422 else if(ext == ".PNG")
423 png_load(filename.c_str(), &ox, &oy);
426 eDebug("[PIC] <format not supportet>");
430 eDebug("[FULLPIC] x-size=%d, y-size=%d", ox, oy);
438 case 1: aspect_ratio = 1.777 / ((double)720/576); break; //16:9
439 case 2: aspect_ratio = 1.600 / ((double)720/576); break; //16:10
440 //case 3: aspect_ratio = 1.250 / ((double)720/576); break; //5:4
441 default: aspect_ratio = 1.333 / ((double)720/576); //4:3
444 if((aspect_ratio * oy * w / ox) <= h)
447 imy = (int)(aspect_ratio*oy*w/ox);
451 imx = (int)((1.0/aspect_ratio)*ox*h/oy);
455 if(resize_mode) pic_buffer = color_resize(pic_buffer, ox, oy, imx, imy);
456 else pic_buffer = simple_resize(pic_buffer, ox, oy, imx, imy);
463 jpeg_save(pic_buffer, cachefile.c_str(), 50, oy, ox);
464 eDebug("[SAVEPIC] x-size=%d, y-size=%d", ox, oy);
470 result=new gPixmap(eSize(w, h), 32);
471 gSurface *surface = result->surface;
474 int o_y=0, u_y=0, v_x=0, h_x=0;
475 unsigned char clear[4] = {0x00,0x00,0x00,0x00};
476 if(background) clear[3]=0xFF;
477 unsigned char *tmp_buffer = new unsigned char[4];
490 //eDebug("o_y=%d u_y=%d v_x=%d h_x=%d", o_y, u_y, v_x, h_x);
493 for(a=0; a<(o_y*ox)+1; a++, nc+=4)
495 memcpy(tmp_buffer, clear, sizeof(clear));
496 tmp_buffer=((unsigned char *)(surface->data)) + nc;
502 for(b=0; b<v_x; b++, nc+=4)
504 memcpy(tmp_buffer, clear, sizeof(clear));
505 tmp_buffer=((unsigned char *)(surface->data)) + nc;
508 for(b=0; b<(ox*3); b+=3, nc+=4)
511 tmp_buffer[2]=pic_buffer[oc++];
512 tmp_buffer[1]=pic_buffer[oc++];
513 tmp_buffer[0]=pic_buffer[oc++];
515 tmp_buffer=((unsigned char *)(surface->data)) + nc;
519 for(b=0; b<h_x; b++, nc+=4)
521 memcpy(tmp_buffer, clear, sizeof(clear));
522 tmp_buffer=((unsigned char *)(surface->data)) + nc;
527 for(a=0; a<(u_y*ox)+1; a++, nc+=4)
529 memcpy(tmp_buffer, clear, sizeof(clear));
530 tmp_buffer=((unsigned char *)(surface->data)) + nc;
533 //eDebug("[PIC] buffer=%d, nc=%d oc=%d ox=%d, oy=%d",w*h*4, nc, oc, ox, oy);
535 surface->clut.data=0;
536 surface->clut.colors=0;
537 surface->clut.start=0;
539 delete [] pic_buffer;