1 #define PNG_SKIP_SETJMP_CHECK
5 #include <lib/gdi/picload.h>
6 #include <lib/gdi/picexif.h>
13 extern const uint32_t crc32_table[256];
17 static std::string getSize(const char* file)
20 if (stat64(file, &s) < 0)
23 snprintf(tmp, 20, "%ld kB",(long)s.st_size / 1024);
27 static unsigned char *conv24to32(unsigned char *orgin, int size, unsigned char alpha = 0xFF)
30 unsigned char *cr = new unsigned char[size * 4];
33 eDebug("[Picload] Error malloc");
37 for (s = 0, d = 0 ; s < (size * 3); s += 3, d += 4 )
40 cr[d+1] = orgin[s + 1];
41 cr[d+2] = orgin[s + 2];
48 static unsigned char *simple_resize(unsigned char *orgin, int ox, int oy, int dx, int dy, int bypp)
50 unsigned char *cr, *p, *l;
52 cr = new unsigned char[dx * dy * bypp];
55 eDebug("[Picload] Error malloc");
60 for (j = 0; j < dy; j++,l += dx * bypp)
62 p = orgin + (j * oy / dy * ox * bypp);
63 for (i = 0, k = 0; i < dx; i++, k += bypp)
65 ip = i * ox / dx * bypp;
69 if(bypp == 4) l[k+3] = p[ip + 3];
76 static unsigned char *color_resize(unsigned char * orgin, int ox, int oy, int dx, int dy, int bypp)
78 unsigned char *cr, *p, *q;
79 int i, j, k, l, xa, xb, ya, yb;
81 cr = new unsigned char[dx * dy * bypp];
84 eDebug("[Picload] Error malloc");
89 for (j = 0; j < dy; j++)
91 for (i = 0; i < dx; i++, p += bypp)
95 xb = (i + 1) * ox / dx;
98 yb = (j + 1) * oy / dy;
101 for (l = ya, r = 0, g = 0, b = 0, a = 0, sq = 0; l <= yb; l++)
103 q = orgin + ((l * ox + xa) * bypp);
104 for (k = xa; k <= xb; k++, q += bypp, sq++)
106 r += q[0]; g += q[1]; b += q[2];
107 if(bypp == 4) a += q[3];
110 p[0] = r / sq; p[1] = g / sq; p[2] = b / sq;
111 if(bypp == 4) p[3] = a / sq;
118 //---------------------------------------------------------------------------------------------
120 #define BMP_TORASTER_OFFSET 10
121 #define BMP_SIZE_OFFSET 18
122 #define BMP_BPP_OFFSET 28
123 #define BMP_RLE_OFFSET 30
124 #define BMP_COLOR_OFFSET 54
126 #define fill4B(a) ((4 - ((a) % 4 )) & 0x03)
134 static void fetch_pallete(int fd, struct color pallete[], int count)
136 unsigned char buff[4];
137 lseek(fd, BMP_COLOR_OFFSET, SEEK_SET);
138 for (int i = 0; i < count; i++)
141 pallete[i].red = buff[2];
142 pallete[i].green = buff[1];
143 pallete[i].blue = buff[0];
147 static unsigned char *bmp_load(const char *file, int *x, int *y)
149 unsigned char buff[4];
150 struct color pallete[256];
152 int fd = open(file, O_RDONLY);
153 if (fd == -1) return NULL;
154 if (lseek(fd, BMP_SIZE_OFFSET, SEEK_SET) == -1) return NULL;
156 *x = buff[0] + (buff[1] << 8) + (buff[2] << 16) + (buff[3] << 24);
158 *y = buff[0] + (buff[1] << 8) + (buff[2] << 16) + (buff[3] << 24);
159 if (lseek(fd, BMP_TORASTER_OFFSET, SEEK_SET) == -1) return NULL;
161 int raster = buff[0] + (buff[1] << 8) + (buff[2] << 16) + (buff[3] << 24);
162 if (lseek(fd, BMP_BPP_OFFSET, SEEK_SET) == -1) return NULL;
164 int bpp = buff[0] + (buff[1] << 8);
166 unsigned char *pic_buffer = new unsigned char[(*x) * (*y) * 3];
167 unsigned char *wr_buffer = pic_buffer + (*x) * ((*y) - 1) * 3;
173 int skip = fill4B((*x) / 2 + (*x) % 2);
174 fetch_pallete(fd, pallete, 16);
175 lseek(fd, raster, SEEK_SET);
176 unsigned char * tbuffer = new unsigned char[*x / 2 + 1];
179 for (int i = 0; i < *y; i++)
181 read(fd, tbuffer, (*x) / 2 + *x % 2);
183 for (j = 0; j < (*x) / 2; j++)
185 unsigned char c1 = tbuffer[j] >> 4;
186 unsigned char c2 = tbuffer[j] & 0x0f;
187 *wr_buffer++ = pallete[c1].red;
188 *wr_buffer++ = pallete[c1].green;
189 *wr_buffer++ = pallete[c1].blue;
190 *wr_buffer++ = pallete[c2].red;
191 *wr_buffer++ = pallete[c2].green;
192 *wr_buffer++ = pallete[c2].blue;
196 unsigned char c1 = tbuffer[j] >> 4;
197 *wr_buffer++ = pallete[c1].red;
198 *wr_buffer++ = pallete[c1].green;
199 *wr_buffer++ = pallete[c1].blue;
202 read(fd, buff, skip);
203 wr_buffer -= (*x) * 6;
209 int skip = fill4B(*x);
210 fetch_pallete(fd, pallete, 256);
211 lseek(fd, raster, SEEK_SET);
212 unsigned char * tbuffer = new unsigned char[*x];
215 for (int i = 0; i < *y; i++)
217 read(fd, tbuffer, *x);
218 for (int j = 0; j < *x; j++)
220 wr_buffer[j * 3] = pallete[tbuffer[j]].red;
221 wr_buffer[j * 3 + 1] = pallete[tbuffer[j]].green;
222 wr_buffer[j * 3 + 2] = pallete[tbuffer[j]].blue;
225 read(fd, buff, skip);
226 wr_buffer -= (*x) * 3;
232 int skip = fill4B((*x) * 3);
233 lseek(fd, raster, SEEK_SET);
234 for (int i = 0; i < (*y); i++)
236 read(fd, wr_buffer, (*x) * 3);
237 for (int j = 0; j < (*x) * 3 ; j = j + 3)
239 unsigned char c = wr_buffer[j];
240 wr_buffer[j] = wr_buffer[j + 2];
241 wr_buffer[j + 2] = c;
244 read(fd, buff, skip);
245 wr_buffer -= (*x) * 3;
257 //---------------------------------------------------------------------
259 static unsigned char *png_load(const char *file, int *ox, int *oy, int *_bypp)
261 static const png_color_16 my_background = {0, 0, 0, 0, 0};
263 png_uint_32 width, height;
265 int bit_depth, color_type, interlace_type;
269 if (!(fh = fopen(file, "rb")))
272 png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
275 png_infop info_ptr = png_create_info_struct(png_ptr);
276 if (info_ptr == NULL)
278 png_destroy_read_struct(&png_ptr, (png_infopp)NULL, (png_infopp)NULL);
283 if (setjmp(png_ptr->jmpbuf))
285 png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL);
290 png_init_io(png_ptr, fh);
292 png_read_info(png_ptr, info_ptr);
293 png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, &interlace_type, NULL, NULL);
295 if ((color_type & PNG_COLOR_TYPE_PALETTE)||(color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8)||(png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)))
296 png_set_expand(png_ptr);
298 png_set_strip_16(png_ptr);
299 if (color_type == PNG_COLOR_TYPE_GRAY || color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
300 png_set_gray_to_rgb(png_ptr);
302 int number_passes = png_set_interlace_handling(png_ptr);
303 png_read_update_info(png_ptr, info_ptr);
304 int bypp = png_get_rowbytes(png_ptr, info_ptr) / width;
306 if(bypp != 4 && bypp != 3)
308 eDebug("[Picload] Error processing");
309 png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL);
314 unsigned char *pic_buffer = new unsigned char[height * width * bypp];
319 for(int pass = 0; pass < number_passes; pass++)
321 fbptr = (png_byte *)pic_buffer;
322 for (i = 0; i < height; i++, fbptr += width * bypp)
323 png_read_row(png_ptr, fbptr, NULL);
325 png_read_end(png_ptr, info_ptr);
326 png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL);
331 //-------------------------------------------------------------------
333 struct r_jpeg_error_mgr
335 struct jpeg_error_mgr pub;
339 void jpeg_cb_error_exit(j_common_ptr cinfo)
341 struct r_jpeg_error_mgr *mptr;
342 mptr = (struct r_jpeg_error_mgr *) cinfo->err;
343 (*cinfo->err->output_message) (cinfo);
344 longjmp(mptr->envbuffer, 1);
347 static unsigned char *jpeg_load(const char *file, int *ox, int *oy)
349 struct jpeg_decompress_struct cinfo;
350 struct jpeg_decompress_struct *ciptr = &cinfo;
351 struct r_jpeg_error_mgr emgr;
353 unsigned char *pic_buffer=NULL;
355 if (!(fh = fopen(file, "rb")))
358 ciptr->err = jpeg_std_error(&emgr.pub);
359 emgr.pub.error_exit = jpeg_cb_error_exit;
360 if (setjmp(emgr.envbuffer) == 1)
362 jpeg_destroy_decompress(ciptr);
367 jpeg_create_decompress(ciptr);
368 jpeg_stdio_src(ciptr, fh);
369 jpeg_read_header(ciptr, TRUE);
370 ciptr->out_color_space = JCS_RGB;
371 ciptr->scale_denom = 1;
373 jpeg_start_decompress(ciptr);
375 *ox=ciptr->output_width;
376 *oy=ciptr->output_height;
378 if(ciptr->output_components == 3)
380 JSAMPLE *lb = (JSAMPLE *)(*ciptr->mem->alloc_small)((j_common_ptr) ciptr, JPOOL_PERMANENT, ciptr->output_width * ciptr->output_components);
381 pic_buffer = new unsigned char[ciptr->output_height * ciptr->output_width * ciptr->output_components];
382 unsigned char *bp = pic_buffer;
384 while (ciptr->output_scanline < ciptr->output_height)
386 jpeg_read_scanlines(ciptr, &lb, 1);
387 memcpy(bp, lb, ciptr->output_width * ciptr->output_components);
388 bp += ciptr->output_width * ciptr->output_components;
391 jpeg_finish_decompress(ciptr);
392 jpeg_destroy_decompress(ciptr);
398 static int jpeg_save(const char * filename, int ox, int oy, unsigned char *pic_buffer)
400 struct jpeg_compress_struct cinfo;
401 struct jpeg_error_mgr jerr;
403 JSAMPROW row_pointer[1];
406 cinfo.err = jpeg_std_error(&jerr);
407 jpeg_create_compress(&cinfo);
409 if ((outfile = fopen(filename, "wb")) == NULL)
411 eDebug("[Picload] jpeg can't open %s", filename);
414 eDebug("[Picload] save Thumbnail... %s",filename);
416 jpeg_stdio_dest(&cinfo, outfile);
418 cinfo.image_width = ox;
419 cinfo.image_height = oy;
420 cinfo.input_components = 3;
421 cinfo.in_color_space = JCS_RGB;
422 jpeg_set_defaults(&cinfo);
423 jpeg_set_quality(&cinfo, 70, TRUE );
424 jpeg_start_compress(&cinfo, TRUE);
426 while (cinfo.next_scanline < cinfo.image_height)
428 row_pointer[0] = & pic_buffer[cinfo.next_scanline * row_stride];
429 (void) jpeg_write_scanlines(&cinfo, row_pointer, 1);
431 jpeg_finish_compress(&cinfo);
433 jpeg_destroy_compress(&cinfo);
437 //-------------------------------------------------------------------
439 inline void m_rend_gif_decodecolormap(unsigned char *cmb, unsigned char *rgbb, ColorMapObject *cm, int s, int l)
441 GifColorType *cmentry;
443 for (i = 0; i < l; i++)
445 cmentry = &cm->Colors[cmb[i]];
446 *(rgbb++) = cmentry->Red;
447 *(rgbb++) = cmentry->Green;
448 *(rgbb++) = cmentry->Blue;
452 static unsigned char *gif_load(const char *file, int *ox, int *oy)
454 unsigned char *pic_buffer = NULL;
455 int px, py, i, j, ibxs;
456 unsigned char *fbptr;
457 unsigned char *lb=NULL;
458 unsigned char *slb=NULL;
461 GifByteType *extension;
462 ColorMapObject *cmap;
466 gft = DGifOpenFileName(file);
471 if (DGifGetRecordType(gft, &rt) == GIF_ERROR)
475 case IMAGE_DESC_RECORD_TYPE:
476 if (DGifGetImageDesc(gft) == GIF_ERROR)
478 *ox = px = gft->Image.Width;
479 *oy = py = gft->Image.Height;
480 pic_buffer = new unsigned char[px * py * 3];
481 lb = (unsigned char *)malloc(px * 3);
482 slb = (unsigned char *) malloc(px);
484 if (lb != NULL && slb != NULL)
486 cmap = (gft->Image.ColorMap ? gft->Image.ColorMap : gft->SColorMap);
487 cmaps = cmap->ColorCount;
491 if (!(gft->Image.Interlace))
493 for (i = 0; i < py; i++, fbptr += px * 3)
495 if (DGifGetLine(gft, slb, px) == GIF_ERROR)
497 m_rend_gif_decodecolormap(slb, lb, cmap, cmaps, px);
498 memcpy(fbptr, lb, px * 3);
503 for (j = 0; j < 4; j++)
506 for (i = 0; i < py; i++, fbptr += px * 3)
508 if (DGifGetLine(gft, slb, px) == GIF_ERROR)
510 m_rend_gif_decodecolormap(slb, lb, cmap, cmaps, px);
511 memcpy(fbptr, lb, px * 3);
527 case EXTENSION_RECORD_TYPE:
528 if (DGifGetExtension(gft, &extcode, &extension) == GIF_ERROR)
530 while (extension != NULL)
531 if (DGifGetExtensionNext(gft, &extension) == GIF_ERROR)
538 while (rt != TERMINATE_RECORD_TYPE);
543 eDebug("[Picload] <Error gif>");
550 //---------------------------------------------------------------------------------------------
553 :msg_thread(this,1), msg_main(eApp,1)
555 CONNECT(msg_thread.recv_msg, ePicLoad::gotMessage);
556 CONNECT(msg_main.recv_msg, ePicLoad::gotMessage);
558 threadrunning = false;
562 m_conf.aspect_ratio = 1.066400; //4:3
563 m_conf.usecache = false;
564 m_conf.resizetype = 1;
565 memset(m_conf.background,0x00,sizeof(m_conf.background));
566 m_conf.thumbnailsize = 180;
569 void ePicLoad::waitFinished()
571 msg_thread.send(Message(Message::quit));
575 ePicLoad::~ePicLoad()
579 if(m_filepara != NULL)
583 void ePicLoad::thread_finished()
588 void ePicLoad::thread()
596 void ePicLoad::decodePic()
598 eDebug("[Picload] decode picture... %s",m_filepara->file);
600 switch(m_filepara->id)
602 case F_PNG: m_filepara->pic_buffer = png_load(m_filepara->file, &m_filepara->ox, &m_filepara->oy, &m_filepara->bypp); break;
603 case F_JPEG: m_filepara->pic_buffer = jpeg_load(m_filepara->file, &m_filepara->ox, &m_filepara->oy); break;
604 case F_BMP: m_filepara->pic_buffer = bmp_load(m_filepara->file, &m_filepara->ox, &m_filepara->oy); break;
605 case F_GIF: m_filepara->pic_buffer = gif_load(m_filepara->file, &m_filepara->ox, &m_filepara->oy); break;
608 if(m_filepara->pic_buffer != NULL)
614 void ePicLoad::decodeThumb()
616 eDebug("[Picload] get Thumbnail... %s",m_filepara->file);
618 bool exif_thumbnail = false;
619 bool cachefile_found = false;
620 std::string cachefile = "";
621 std::string cachedir = "/.Thumbnails";
623 if(m_filepara->id == F_JPEG)
625 Cexif *exif = new Cexif;
626 if(exif->DecodeExif(m_filepara->file, 1))
628 if(exif->m_exifinfo->IsExif)
630 if(exif->m_exifinfo->Thumnailstate==2)
632 m_filepara->file = strdup(THUMBNAILTMPFILE);
633 exif_thumbnail = true;
634 eDebug("[Picload] Exif Thumbnail found");
636 m_filepara->addExifInfo(exif->m_exifinfo->CameraMake);
637 m_filepara->addExifInfo(exif->m_exifinfo->CameraModel);
638 m_filepara->addExifInfo(exif->m_exifinfo->DateTime);
640 snprintf(buf, 20, "%d x %d", exif->m_exifinfo->Width, exif->m_exifinfo->Height);
641 m_filepara->addExifInfo(buf);
648 if((! exif_thumbnail) && m_conf.usecache)
650 if(FILE *f=fopen(m_filepara->file, "rb"))
653 int count = 1024*100;
654 unsigned long crc32 = 0;
655 char crcstr[9];*crcstr=0;
657 while ((c=getc(f))!=EOF)
659 crc32 = crc32_table[((crc32) ^ (c)) & 0xFF] ^ ((crc32) >> 8);
660 if(--count < 0) break;
665 sprintf(crcstr, "%08lX", crc32);
667 cachedir = m_filepara->file;
668 unsigned int pos = cachedir.find_last_of("/");
669 if (pos != std::string::npos)
670 cachedir = cachedir.substr(0, pos) + "/.Thumbnails";
672 cachefile = cachedir + std::string("/pc_") + crcstr;
673 if(!access(cachefile.c_str(), R_OK))
675 cachefile_found = true;
676 m_filepara->file = strdup(cachefile.c_str());
677 m_filepara->id = F_JPEG;
678 eDebug("[Picload] Cache File found");
683 switch(m_filepara->id)
685 case F_PNG: m_filepara->pic_buffer = png_load(m_filepara->file, &m_filepara->ox, &m_filepara->oy, &m_filepara->bypp); break;
686 case F_JPEG: m_filepara->pic_buffer = jpeg_load(m_filepara->file, &m_filepara->ox, &m_filepara->oy); break;
687 case F_BMP: m_filepara->pic_buffer = bmp_load(m_filepara->file, &m_filepara->ox, &m_filepara->oy); break;
688 case F_GIF: m_filepara->pic_buffer = gif_load(m_filepara->file, &m_filepara->ox, &m_filepara->oy); break;
692 ::unlink(THUMBNAILTMPFILE);
694 if(m_filepara->pic_buffer != NULL)
697 if(m_conf.usecache && (! exif_thumbnail) && (! cachefile_found))
699 if(access(cachedir.c_str(), R_OK))
700 ::mkdir(cachedir.c_str(), 0755);
702 //resize for Thumbnail
704 if (m_filepara->ox <= m_filepara->oy)
706 imy = m_conf.thumbnailsize;
707 imx = (int)( (m_conf.thumbnailsize * ((double)m_filepara->ox)) / ((double)m_filepara->oy) );
711 imx = m_conf.thumbnailsize;
712 imy = (int)( (m_conf.thumbnailsize * ((double)m_filepara->oy)) / ((double)m_filepara->ox) );
715 m_filepara->pic_buffer = color_resize(m_filepara->pic_buffer, m_filepara->ox, m_filepara->oy, imx, imy, m_filepara->bypp);
716 m_filepara->ox = imx;
717 m_filepara->oy = imy;
719 if(jpeg_save(cachefile.c_str(), m_filepara->ox, m_filepara->oy, m_filepara->pic_buffer))
720 eDebug("[Picload] error saving cachefile");
727 void ePicLoad::resizePic()
731 if((m_conf.aspect_ratio * m_filepara->oy * m_filepara->max_x / m_filepara->ox) <= m_filepara->max_y)
733 imx = m_filepara->max_x;
734 imy = (int)(m_conf.aspect_ratio * m_filepara->oy * m_filepara->max_x / m_filepara->ox);
738 imx = (int)((1.0/m_conf.aspect_ratio) * m_filepara->ox * m_filepara->max_y / m_filepara->oy);
739 imy = m_filepara->max_y;
742 if(m_conf.resizetype)
743 m_filepara->pic_buffer = color_resize(m_filepara->pic_buffer, m_filepara->ox, m_filepara->oy, imx, imy, m_filepara->bypp);
745 m_filepara->pic_buffer = simple_resize(m_filepara->pic_buffer, m_filepara->ox, m_filepara->oy, imx, imy, m_filepara->bypp);
747 m_filepara->ox = imx;
748 m_filepara->oy = imy;
751 void ePicLoad::gotMessage(const Message &msg)
755 case Message::decode_Pic:
757 msg_main.send(Message(Message::decode_finished));
759 case Message::decode_Thumb:
761 msg_main.send(Message(Message::decode_finished));
763 case Message::quit: // called from decode thread
764 eDebug("[Picload] decode thread ... got quit msg");
767 case Message::decode_finished: // called from main thread
768 //eDebug("[Picload] decode finished... %s", m_filepara->file);
769 if(m_filepara->callback)
771 PictureData(m_filepara->picinfo.c_str());
775 if(m_filepara != NULL)
783 eDebug("unhandled thread message");
787 int ePicLoad::startThread(int what, const char *file, int x, int y, bool async)
789 if(async && threadrunning && m_filepara != NULL)
791 eDebug("[Picload] thread running");
792 m_filepara->callback = false;
796 if(m_filepara != NULL)
803 unsigned char id[10];
804 int fd = ::open(file, O_RDONLY);
805 if (fd == -1) return 1;
809 if(id[1] == 'P' && id[2] == 'N' && id[3] == 'G') file_id = F_PNG;
810 else if(id[6] == 'J' && id[7] == 'F' && id[8] == 'I' && id[9] == 'F') file_id = F_JPEG;
811 else if(id[0] == 0xff && id[1] == 0xd8 && id[2] == 0xff) file_id = F_JPEG;
812 else if(id[0] == 'B' && id[1] == 'M' ) file_id = F_BMP;
813 else if(id[0] == 'G' && id[1] == 'I' && id[2] == 'F') file_id = F_GIF;
817 eDebug("[Picload] <format not supportet>");
821 m_filepara = new Cfilepara(file, file_id, getSize(file));
822 x > 0 ? m_filepara->max_x = x : m_filepara->max_x = m_conf.max_x;
823 y > 0 ? m_filepara->max_y = y : m_filepara->max_y = m_conf.max_y;
825 if(m_filepara->max_x <= 0 || m_filepara->max_y <= 0)
829 eDebug("[Picload] <error in Para>");
835 msg_thread.send(Message(Message::decode_Pic));
837 msg_thread.send(Message(Message::decode_Thumb));
847 RESULT ePicLoad::startDecode(const char *file, int x, int y, bool async)
849 return startThread(1, file, x, y, async);
852 RESULT ePicLoad::getThumbnail(const char *file, int x, int y, bool async)
854 return startThread(0, file, x, y, async);
857 PyObject *ePicLoad::getInfo(const char *filename)
861 Cexif *exif = new Cexif;
862 if(exif->DecodeExif(filename))
864 if(exif->m_exifinfo->IsExif)
868 list = PyList_New(23);
869 PyList_SET_ITEM(list, pos++, PyString_FromString(filename));
870 PyList_SET_ITEM(list, pos++, PyString_FromString(exif->m_exifinfo->Version));
871 PyList_SET_ITEM(list, pos++, PyString_FromString(exif->m_exifinfo->CameraMake));
872 PyList_SET_ITEM(list, pos++, PyString_FromString(exif->m_exifinfo->CameraModel));
873 PyList_SET_ITEM(list, pos++, PyString_FromString(exif->m_exifinfo->DateTime));
874 PyList_SET_ITEM(list, pos++, PyString_FromFormat("%d x %d", exif->m_exifinfo->Width, exif->m_exifinfo->Height));
875 PyList_SET_ITEM(list, pos++, PyString_FromString(exif->m_exifinfo->FlashUsed));
876 PyList_SET_ITEM(list, pos++, PyString_FromString(exif->m_exifinfo->Orientation));
877 PyList_SET_ITEM(list, pos++, PyString_FromString(exif->m_exifinfo->Comments));
878 PyList_SET_ITEM(list, pos++, PyString_FromString(exif->m_exifinfo->MeteringMode));
879 PyList_SET_ITEM(list, pos++, PyString_FromString(exif->m_exifinfo->ExposureProgram));
880 PyList_SET_ITEM(list, pos++, PyString_FromString(exif->m_exifinfo->LightSource));
881 PyList_SET_ITEM(list, pos++, PyString_FromFormat("%d", exif->m_exifinfo->CompressionLevel));
882 PyList_SET_ITEM(list, pos++, PyString_FromFormat("%d", exif->m_exifinfo->ISOequivalent));
883 sprintf(tmp, "%.2f", exif->m_exifinfo->Xresolution);
884 PyList_SET_ITEM(list, pos++, PyString_FromString(tmp));
885 sprintf(tmp, "%.2f", exif->m_exifinfo->Yresolution);
886 PyList_SET_ITEM(list, pos++, PyString_FromString(tmp));
887 PyList_SET_ITEM(list, pos++, PyString_FromString(exif->m_exifinfo->ResolutionUnit));
888 sprintf(tmp, "%.2f", exif->m_exifinfo->Brightness);
889 PyList_SET_ITEM(list, pos++, PyString_FromString(tmp));
890 sprintf(tmp, "%.5f sec.", exif->m_exifinfo->ExposureTime);
891 PyList_SET_ITEM(list, pos++, PyString_FromString(tmp));
892 sprintf(tmp, "%.5f", exif->m_exifinfo->ExposureBias);
893 PyList_SET_ITEM(list, pos++, PyString_FromString(tmp));
894 sprintf(tmp, "%.5f", exif->m_exifinfo->Distance);
895 PyList_SET_ITEM(list, pos++, PyString_FromString(tmp));
896 sprintf(tmp, "%.5f", exif->m_exifinfo->CCDWidth);
897 PyList_SET_ITEM(list, pos++, PyString_FromString(tmp));
898 sprintf(tmp, "%.2f", exif->m_exifinfo->ApertureFNumber);
899 PyList_SET_ITEM(list, pos++, PyString_FromString(tmp));
903 list = PyList_New(2);
904 PyList_SET_ITEM(list, 0, PyString_FromString(filename));
905 PyList_SET_ITEM(list, 1, PyString_FromString(exif->m_szLastError));
911 list = PyList_New(2);
912 PyList_SET_ITEM(list, 0, PyString_FromString(filename));
913 PyList_SET_ITEM(list, 1, PyString_FromString(exif->m_szLastError));
917 return list ? (PyObject*)list : (PyObject*)PyList_New(0);
920 int ePicLoad::getData(ePtr<gPixmap> &result)
923 if(m_filepara->pic_buffer == NULL) return 0;
925 if(m_filepara->bypp == 3)
927 m_filepara->pic_buffer = conv24to32(m_filepara->pic_buffer, m_filepara->ox * m_filepara->oy);
930 result=new gPixmap(eSize(m_filepara->max_x, m_filepara->max_y), 32);
931 gSurface *surface = result->surface;
934 int o_y=0, u_y=0, v_x=0, h_x=0;
936 unsigned char *tmp_buffer=((unsigned char *)(surface->data));
938 if(m_filepara->oy < m_filepara->max_y)
940 o_y = (m_filepara->max_y - m_filepara->oy) / 2;
941 u_y = m_filepara->max_y - m_filepara->oy - o_y;
943 if(m_filepara->ox < m_filepara->max_x)
945 v_x = (m_filepara->max_x - m_filepara->ox) / 2;
946 h_x = m_filepara->max_x - m_filepara->ox - v_x;
949 if(m_filepara->oy < m_filepara->max_y)
951 for(a=0; a<(o_y*m_filepara->ox); a++, nc+=4)
953 tmp_buffer=((unsigned char *)(surface->data)) + nc;
954 memcpy(tmp_buffer, m_conf.background, sizeof(m_conf.background));
958 for(a=0; a<m_filepara->oy; a++)
960 if(m_filepara->ox < m_filepara->max_x)
962 for(b=0; b<v_x; b++, nc+=4)
964 tmp_buffer=((unsigned char *)(surface->data)) + nc;
965 memcpy(tmp_buffer, m_conf.background, sizeof(m_conf.background));
969 for(b=0; b<(m_filepara->ox*4); b+=4, nc+=4)
971 tmp_buffer=((unsigned char *)(surface->data)) + nc;
972 tmp_buffer[2] = m_filepara->pic_buffer[oc++];
973 tmp_buffer[1] = m_filepara->pic_buffer[oc++];
974 tmp_buffer[0] = m_filepara->pic_buffer[oc++];
975 tmp_buffer[3] = m_filepara->pic_buffer[oc++];
978 if(m_filepara->ox < m_filepara->max_x)
980 for(b=0; b<h_x; b++, nc+=4)
982 tmp_buffer=((unsigned char *)(surface->data)) + nc;
983 memcpy(tmp_buffer, m_conf.background, sizeof(m_conf.background));
988 if(m_filepara->oy < m_filepara->max_y)
990 for(a=0; a<(u_y*m_filepara->ox); a++, nc+=4)
992 tmp_buffer=((unsigned char *)(surface->data)) + nc;
993 memcpy(tmp_buffer, m_conf.background, sizeof(m_conf.background));
997 surface->clut.data=0;
998 surface->clut.colors=0;
999 surface->clut.start=0;
1007 RESULT ePicLoad::setPara(PyObject *val)
1009 if (!PySequence_Check(val))
1011 if (PySequence_Size(val) < 7)
1014 ePyObject fast = PySequence_Fast(val, "");
1015 m_conf.max_x = PyInt_AsLong( PySequence_Fast_GET_ITEM(fast, 0));
1016 m_conf.max_y = PyInt_AsLong( PySequence_Fast_GET_ITEM(fast, 1));
1017 m_conf.aspect_ratio = (double)PyInt_AsLong( PySequence_Fast_GET_ITEM(fast, 2)) / PyInt_AsLong(PySequence_Fast_GET_ITEM(fast, 3));
1018 m_conf.usecache = PyInt_AsLong( PySequence_Fast_GET_ITEM(fast, 4));
1019 m_conf.resizetype = PyInt_AsLong( PySequence_Fast_GET_ITEM(fast, 5));
1020 const char *bg_str = PyString_AsString( PySequence_Fast_GET_ITEM(fast, 6));
1022 if(bg_str[0] == '#' && strlen(bg_str)==9)
1024 int bg = strtoul(bg_str+1, NULL, 16);
1025 m_conf.background[0] = bg&0xFF; //BB
1026 m_conf.background[1] = (bg>>8)&0xFF; //GG
1027 m_conf.background[2] = (bg>>16)&0xFF; //RR
1028 m_conf.background[3] = bg>>24; //AA
1030 eDebug("[Picload] setPara max-X=%d max-Y=%d aspect_ratio=%lf cache=%d resize=%d bg=#%02X%02X%02X%02X", m_conf.max_x, m_conf.max_y, m_conf.aspect_ratio, (int)m_conf.usecache, (int)m_conf.resizetype, m_conf.background[3], m_conf.background[2], m_conf.background[1], m_conf.background[0]);
1035 //------------------------------------------------------------------------------------
1038 SWIG_VOID(int) loadPic(ePtr<gPixmap> &result, std::string filename, int x, int y, int aspect, int resize_mode, int rotate, int background, std::string cachefile)
1042 eDebug("deprecated loadPic function used!!! please use the non blocking version! you can see demo code in Pictureplayer plugin... this function is removed in the near future!");
1047 case 1: asp1 = 16*576, asp2 = 9*720; break; //16:9
1048 case 2: asp1 = 16*576, asp2 = 10*720; break; //16:10
1049 case 3: asp1 = 5*576, asp2 = 4*720; break; //5:4
1050 default: asp1 = 4*576, asp2 = 3*720; break; //4:3
1053 ePyObject tuple = PyTuple_New(7);
1054 PyTuple_SET_ITEM(tuple, 0, PyLong_FromLong(x));
1055 PyTuple_SET_ITEM(tuple, 1, PyLong_FromLong(y));
1056 PyTuple_SET_ITEM(tuple, 2, PyLong_FromLong(asp1));
1057 PyTuple_SET_ITEM(tuple, 3, PyLong_FromLong(asp2));
1058 PyTuple_SET_ITEM(tuple, 4, PyLong_FromLong(0));
1059 PyTuple_SET_ITEM(tuple, 5, PyLong_FromLong(resize_mode));
1061 PyTuple_SET_ITEM(tuple, 6, PyString_FromString("#ff000000"));
1063 PyTuple_SET_ITEM(tuple, 6, PyString_FromString("#00000000"));
1067 if(!mPL.startDecode(filename.c_str(), 0, 0, false))
1068 mPL.getData(result);