X-Git-Url: http://code.vuplus.com/gitweb/?p=vuplus_dvbapp;a=blobdiff_plain;f=lib%2Fgdi%2Fpicload.cpp;h=ab7a0b5d35870a3f59a5f235e63969d504a5a304;hp=1f9bed489910acb16c6c4087d5f82446f06a5a25;hb=HEAD;hpb=fde1aa8770d42e9a5abb598f1db3c54045f0d8c8 diff --git a/lib/gdi/picload.cpp b/lib/gdi/picload.cpp index 1f9bed4..ab7a0b5 100644 --- a/lib/gdi/picload.cpp +++ b/lib/gdi/picload.cpp @@ -1,38 +1,39 @@ -#include // must be included before Python.h because of setjmp -#include -#include "picexif.h" -#include - +#define PNG_SKIP_SETJMP_CHECK +#include #include -#include -#include -#include -#include // savePNG need it - -#define JDCT_DEFAULT JDCT_IFAST +#include +#include extern "C" { #include #include -//#include "transupp.h" } -unsigned char *pic_buffer=NULL; +extern const uint32_t crc32_table[256]; + +DEFINE_REF(ePicLoad); + +static std::string getSize(const char* file) +{ + struct stat64 s; + if (stat64(file, &s) < 0) + return ""; + char tmp[20]; + snprintf(tmp, 20, "%ld kB",(long)s.st_size / 1024); + return tmp; +} -static unsigned char *conv24to32(unsigned char * orgin, int size, int background = 0) +static unsigned char *conv24to32(unsigned char *orgin, int size, unsigned char alpha = 0xFF) { int s, d; unsigned char *cr = new unsigned char[size * 4]; if (cr == NULL) { - printf("[CONV32] Error: malloc\n"); + eDebug("[Picload] Error malloc"); return(orgin); } - unsigned char alpha = 0x00; - if(background) alpha = 0xFF; - for (s = 0, d = 0 ; s < (size * 3); s += 3, d += 4 ) { cr[d] = orgin[s]; @@ -44,50 +45,50 @@ static unsigned char *conv24to32(unsigned char * orgin, int size, int background return(cr); } -static unsigned char *simple_resize(unsigned char * orgin, int ox, int oy, int dx, int dy) +static unsigned char *simple_resize(unsigned char *orgin, int ox, int oy, int dx, int dy, int bypp) { unsigned char *cr, *p, *l; int i, j, k, ip; - cr = new unsigned char[dx * dy * 4]; + cr = new unsigned char[dx * dy * bypp]; if (cr == NULL) { - printf("[RESIZE] Error: malloc\n"); + eDebug("[Picload] Error malloc"); return(orgin); } l = cr; - for (j = 0; j < dy; j++,l += dx * 4) + for (j = 0; j < dy; j++,l += dx * bypp) { - p = orgin + (j * oy / dy * ox * 4); - for (i = 0, k = 0; i < dx; i++, k += 4) + p = orgin + (j * oy / dy * ox * bypp); + for (i = 0, k = 0; i < dx; i++, k += bypp) { - ip = i * ox / dx * 4; + ip = i * ox / dx * bypp; l[k] = p[ip]; l[k+1] = p[ip + 1]; l[k+2] = p[ip + 2]; - l[k+3] = p[ip + 3]; + if(bypp == 4) l[k+3] = p[ip + 3]; } } delete [] orgin; return(cr); } -static unsigned char *color_resize(unsigned char * orgin, int ox, int oy, int dx, int dy) +static unsigned char *color_resize(unsigned char * orgin, int ox, int oy, int dx, int dy, int bypp) { unsigned char *cr, *p, *q; int i, j, k, l, xa, xb, ya, yb; int sq, r, g, b, a; - cr = new unsigned char[dx * dy * 4]; + cr = new unsigned char[dx * dy * bypp]; if (cr == NULL) { - printf("[RESIZE] Error: malloc\n"); + eDebug("[Picload] Error malloc"); return(orgin); } p = cr; for (j = 0; j < dy; j++) { - for (i = 0; i < dx; i++, p += 4) + for (i = 0; i < dx; i++, p += bypp) { xa = i * ox / dx; ya = j * oy / dy; @@ -99,267 +100,21 @@ static unsigned char *color_resize(unsigned char * orgin, int ox, int oy, int dx yb = oy - 1; for (l = ya, r = 0, g = 0, b = 0, a = 0, sq = 0; l <= yb; l++) { - q = orgin + ((l * ox + xa) * 4); - for (k = xa; k <= xb; k++, q += 4, sq++) + q = orgin + ((l * ox + xa) * bypp); + for (k = xa; k <= xb; k++, q += bypp, sq++) { - r += q[0]; g += q[1]; b += q[2]; a += q[3]; + r += q[0]; g += q[1]; b += q[2]; + if(bypp == 4) a += q[3]; } } - p[0] = r / sq; p[1] = g / sq; p[2] = b / sq; p[3] = a / sq; + p[0] = r / sq; p[1] = g / sq; p[2] = b / sq; + if(bypp == 4) p[3] = a / sq; } } delete [] orgin; return(cr); } -//------------------------------------------------------------------- - -struct r_jpeg_error_mgr -{ - struct jpeg_error_mgr pub; - jmp_buf envbuffer; -}; - -void jpeg_cb_error_exit(j_common_ptr cinfo) -{ - struct r_jpeg_error_mgr *mptr; - mptr = (struct r_jpeg_error_mgr *) cinfo->err; - (*cinfo->err->output_message) (cinfo); - longjmp(mptr->envbuffer, 1); -} - -static int jpeg_save(unsigned char *image_buffer, const char * filename, int quality, int image_height, int image_width) -{ - struct jpeg_compress_struct cinfo; - struct jpeg_error_mgr jerr; - FILE * outfile; /* target file */ - JSAMPROW row_pointer[1];/* pointer to JSAMPLE row[s] */ - int row_stride; /* physical row width in image buffer */ - - cinfo.err = jpeg_std_error(&jerr); - jpeg_create_compress(&cinfo); - - if ((outfile = fopen(filename, "wb")) == NULL) - { - eDebug("[JPEG] can't open %s", filename); - return -1; - } - jpeg_stdio_dest(&cinfo, outfile); - - cinfo.image_width = image_width; - cinfo.image_height = image_height; - cinfo.input_components = 3; - cinfo.in_color_space = JCS_RGB; - jpeg_set_defaults(&cinfo); - jpeg_set_quality(&cinfo, quality, TRUE ); - jpeg_start_compress(&cinfo, TRUE); - row_stride = image_width * 3; - while (cinfo.next_scanline < cinfo.image_height) - { - row_pointer[0] = & image_buffer[cinfo.next_scanline * row_stride]; - (void) jpeg_write_scanlines(&cinfo, row_pointer, 1); - } - jpeg_finish_compress(&cinfo); - fclose(outfile); - jpeg_destroy_compress(&cinfo); - return 0; -} - -/* Expanded data source object for memory buffer input */ -typedef struct -{ - struct jpeg_source_mgr pub; /* public fields */ - FILE *infile; /* source stream */ - JOCTET *buffer; /* start of buffer */ - boolean start_of_file; /* have we gotten any data yet? */ -} mem_source_mgr; - -typedef mem_source_mgr *mem_src_ptr; - -static void init_source (j_decompress_ptr cinfo) -{ - mem_src_ptr src = (mem_src_ptr) cinfo->src; - src->start_of_file = TRUE; -} - -static boolean fill_input_buffer (j_decompress_ptr cinfo) -{ - /* no-op */ (void)cinfo; - return TRUE; - } - -static void skip_input_data (j_decompress_ptr cinfo, long num_bytes) -{ - mem_src_ptr src = (mem_src_ptr) cinfo->src; - - if (num_bytes > 0) - { - src->pub.next_input_byte += (size_t) num_bytes; - src->pub.bytes_in_buffer -= (size_t) num_bytes; - } -} - -static void term_source (j_decompress_ptr cinfo) -{ - /* no-op */ (void)cinfo; -} - -static void jpeg_memory_src (j_decompress_ptr cinfo, unsigned char *inbfr, int len) -{ - mem_src_ptr src; - if (cinfo->src == NULL) - { - cinfo->src = (struct jpeg_source_mgr *) - (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, (size_t)sizeof(mem_source_mgr)); - src = (mem_src_ptr) cinfo->src; - src->buffer = (JOCTET *) inbfr; - } - src = (mem_src_ptr) cinfo->src; - src->pub.init_source = init_source; - src->pub.fill_input_buffer = fill_input_buffer; - src->pub.skip_input_data = skip_input_data; - src->pub.resync_to_restart = jpeg_resync_to_restart; /* use default method */ - src->pub.term_source = term_source; - src->infile = 0L; - src->pub.bytes_in_buffer = len; /* sets to entire file len */ - src->pub.next_input_byte = (JOCTET *)inbfr; /* at start of buffer */ -} - -static int jpeg_load_thumb(const char *filename, int *x, int *y) -{ - struct jpeg_decompress_struct cinfo; - struct jpeg_decompress_struct *ciptr = &cinfo; - struct r_jpeg_error_mgr emgr; - FILE *fh; - - if (!(fh = fopen(filename, "rb"))) - return 0; - - ciptr->err = jpeg_std_error(&emgr.pub); - emgr.pub.error_exit = jpeg_cb_error_exit; - if (setjmp(emgr.envbuffer) == 1) - { - jpeg_destroy_decompress(ciptr); - fclose(fh); - return 0; - } - - jpeg_create_decompress(ciptr); - jpeg_stdio_src(ciptr, fh); - - jpeg_save_markers (ciptr, JPEG_APP0 + 1, 0xffff); - - jpeg_read_header(ciptr, TRUE); - - struct jpeg_marker_struct *m = cinfo.marker_list; - - unsigned char *thumb_buf = NULL; - size_t bufsize; - - if ( m ) - { - unsigned char *p_data = m->data; - while ( p_data < m->data+m->data_length ) - { - if ( p_data[0] == 0xFF && p_data[1] == 0xD8 ) - { - bufsize = (size_t) m->data_length - (size_t) (p_data-m->data); - thumb_buf = new unsigned char[bufsize]; - bufsize = 0; - do { - thumb_buf[bufsize++] = *p_data; - } while ( !(*p_data++ == 0xFF && *p_data == 0xD9) && p_data < m->data+m->data_length ); - thumb_buf[bufsize++] = *p_data; - } - p_data++; - } - } - - if ( thumb_buf != NULL ) - { - jpeg_create_decompress(ciptr); - jpeg_memory_src(ciptr, thumb_buf, bufsize-2); - jpeg_read_header(ciptr, TRUE); - } - else - eDebug("no exif thumbnail found! loading actual image instead"); - - ciptr->out_color_space = JCS_RGB; - ciptr->scale_denom = 1; - - jpeg_start_decompress(ciptr); - - *x=ciptr->output_width; - *y=ciptr->output_height; - - if(ciptr->output_components == 3) - { - JSAMPLE *lb = (JSAMPLE *)(*ciptr->mem->alloc_small)((j_common_ptr) ciptr, JPOOL_PERMANENT, ciptr->output_width * ciptr->output_components); - pic_buffer = new unsigned char[ciptr->output_height * ciptr->output_width * ciptr->output_components]; - unsigned char *bp = pic_buffer; - - while (ciptr->output_scanline < ciptr->output_height) - { - jpeg_read_scanlines(ciptr, &lb, 1); - memcpy(bp, lb, ciptr->output_width * ciptr->output_components); - bp += ciptr->output_width * ciptr->output_components; - } - } - jpeg_finish_decompress(ciptr); - jpeg_destroy_decompress(ciptr); - fclose(fh); - return 1; -} - -static int jpeg_load(const char *filename, int *x, int *y) -{ - struct jpeg_decompress_struct cinfo; - struct jpeg_decompress_struct *ciptr = &cinfo; - struct r_jpeg_error_mgr emgr; - FILE *fh; - - if (!(fh = fopen(filename, "rb"))) - return 0; - - ciptr->err = jpeg_std_error(&emgr.pub); - emgr.pub.error_exit = jpeg_cb_error_exit; - if (setjmp(emgr.envbuffer) == 1) - { - jpeg_destroy_decompress(ciptr); - fclose(fh); - return 0; - } - - jpeg_create_decompress(ciptr); - jpeg_stdio_src(ciptr, fh); - jpeg_read_header(ciptr, TRUE); - ciptr->out_color_space = JCS_RGB; - ciptr->scale_denom = 1; - - jpeg_start_decompress(ciptr); - - *x=ciptr->output_width; - *y=ciptr->output_height; - - if(ciptr->output_components == 3) - { - JSAMPLE *lb = (JSAMPLE *)(*ciptr->mem->alloc_small)((j_common_ptr) ciptr, JPOOL_PERMANENT, ciptr->output_width * ciptr->output_components); - pic_buffer = new unsigned char[ciptr->output_height * ciptr->output_width * ciptr->output_components]; - unsigned char *bp = pic_buffer; - - while (ciptr->output_scanline < ciptr->output_height) - { - jpeg_read_scanlines(ciptr, &lb, 1); - memcpy(bp, lb, ciptr->output_width * ciptr->output_components); - bp += ciptr->output_width * ciptr->output_components; - } - } - jpeg_finish_decompress(ciptr); - jpeg_destroy_decompress(ciptr); - fclose(fh); - return 1; -} - //--------------------------------------------------------------------------------------------- #define BMP_TORASTER_OFFSET 10 @@ -389,26 +144,26 @@ static void fetch_pallete(int fd, struct color pallete[], int count) } } -static int bmp_load(const char *filename, int *x, int *y) +static unsigned char *bmp_load(const char *file, int *x, int *y) { unsigned char buff[4]; struct color pallete[256]; - int fd = open(filename, O_RDONLY); - if (fd == -1) return 0; - if (lseek(fd, BMP_SIZE_OFFSET, SEEK_SET) == -1) return 0; + int fd = open(file, O_RDONLY); + if (fd == -1) return NULL; + if (lseek(fd, BMP_SIZE_OFFSET, SEEK_SET) == -1) return NULL; read(fd, buff, 4); *x = buff[0] + (buff[1] << 8) + (buff[2] << 16) + (buff[3] << 24); read(fd, buff, 4); *y = buff[0] + (buff[1] << 8) + (buff[2] << 16) + (buff[3] << 24); - if (lseek(fd, BMP_TORASTER_OFFSET, SEEK_SET) == -1) return 0; + if (lseek(fd, BMP_TORASTER_OFFSET, SEEK_SET) == -1) return NULL; read(fd, buff, 4); int raster = buff[0] + (buff[1] << 8) + (buff[2] << 16) + (buff[3] << 24); - if (lseek(fd, BMP_BPP_OFFSET, SEEK_SET) == -1) return 0; + if (lseek(fd, BMP_BPP_OFFSET, SEEK_SET) == -1) return NULL; read(fd, buff, 2); int bpp = buff[0] + (buff[1] << 8); - pic_buffer = new unsigned char[(*x) * (*y) * 3]; + unsigned char *pic_buffer = new unsigned char[(*x) * (*y) * 3]; unsigned char *wr_buffer = pic_buffer + (*x) * ((*y) - 1) * 3; switch (bpp) @@ -420,7 +175,7 @@ static int bmp_load(const char *filename, int *x, int *y) lseek(fd, raster, SEEK_SET); unsigned char * tbuffer = new unsigned char[*x / 2 + 1]; if (tbuffer == NULL) - return 0; + return NULL; for (int i = 0; i < *y; i++) { read(fd, tbuffer, (*x) / 2 + *x % 2); @@ -456,7 +211,7 @@ static int bmp_load(const char *filename, int *x, int *y) lseek(fd, raster, SEEK_SET); unsigned char * tbuffer = new unsigned char[*x]; if (tbuffer == NULL) - return 0; + return NULL; for (int i = 0; i < *y; i++) { read(fd, tbuffer, *x); @@ -492,45 +247,44 @@ static int bmp_load(const char *filename, int *x, int *y) break; } default: - return 0; + return NULL; } close(fd); - return 1; + return(pic_buffer); } -//--------------------------------------------------------------------------------------------- -static int png_load(const char *filename, int *x, int *y) +//--------------------------------------------------------------------- + +static unsigned char *png_load(const char *file, int *ox, int *oy, int *_bypp) { static const png_color_16 my_background = {0, 0, 0, 0, 0}; - png_structp png_ptr; - png_infop info_ptr; png_uint_32 width, height; unsigned int i; int bit_depth, color_type, interlace_type; - int number_passes, pass; - png_byte * fbptr; - FILE * fh; + png_byte *fbptr; + FILE *fh; - if (!(fh = fopen(filename, "rb"))) return 0; + if (!(fh = fopen(file, "rb"))) + return NULL; - png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); + png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); if (png_ptr == NULL) - return 0; - info_ptr = png_create_info_struct(png_ptr); + return NULL; + png_infop info_ptr = png_create_info_struct(png_ptr); if (info_ptr == NULL) { png_destroy_read_struct(&png_ptr, (png_infopp)NULL, (png_infopp)NULL); - fclose(fh); - return 0; + fclose(fh); + return NULL; } - if (setjmp(png_ptr->jmpbuf)) + if (setjmp(png_jmpbuf(png_ptr))) { png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL); - fclose(fh); - return 0; + fclose(fh); + return NULL; } png_init_io(png_ptr, fh); @@ -538,48 +292,146 @@ static int png_load(const char *filename, int *x, int *y) png_read_info(png_ptr, info_ptr); png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, &interlace_type, NULL, NULL); - 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))) + 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))) png_set_expand(png_ptr); if (bit_depth == 16) png_set_strip_16(png_ptr); if (color_type == PNG_COLOR_TYPE_GRAY || color_type == PNG_COLOR_TYPE_GRAY_ALPHA) png_set_gray_to_rgb(png_ptr); - number_passes = png_set_interlace_handling(png_ptr); + int number_passes = png_set_interlace_handling(png_ptr); png_read_update_info(png_ptr, info_ptr); + int bypp = png_get_rowbytes(png_ptr, info_ptr) / width; - int bpp = png_get_rowbytes(png_ptr, info_ptr)/width; - if ((bpp !=4) && (bpp !=3)) + if(bypp != 4 && bypp != 3) { - eDebug("[PNG] Error processing"); - return 0; - } - - if (width * height > 1000000) // 1000x1000 or equiv. - { - eDebug("[png_load] image size is %d x %d, which is \"too large\".", (int)width, (int)height); - png_read_end(png_ptr, info_ptr); + eDebug("[Picload] Error processing"); png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL); fclose(fh); - return 0; + return NULL; } - pic_buffer = new unsigned char[width * height * bpp]; - *x=width; - *y=height; + unsigned char *pic_buffer = new unsigned char[height * width * bypp]; + *ox=width; + *oy=height; + *_bypp = bypp; - for(pass = 0; pass < number_passes; pass++) + for(int pass = 0; pass < number_passes; pass++) { fbptr = (png_byte *)pic_buffer; - for (i = 0; i < height; i++, fbptr += width * bpp) + for (i = 0; i < height; i++, fbptr += width * bypp) png_read_row(png_ptr, fbptr, NULL); } png_read_end(png_ptr, info_ptr); png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL); fclose(fh); - if (bpp == 3) - pic_buffer = conv24to32(pic_buffer, width * height, 1); - return 1; + return(pic_buffer); +} + +//------------------------------------------------------------------- + +struct r_jpeg_error_mgr +{ + struct jpeg_error_mgr pub; + jmp_buf envbuffer; +}; + +void jpeg_cb_error_exit(j_common_ptr cinfo) +{ + struct r_jpeg_error_mgr *mptr; + mptr = (struct r_jpeg_error_mgr *) cinfo->err; + (*cinfo->err->output_message) (cinfo); + longjmp(mptr->envbuffer, 1); +} + +static unsigned char *jpeg_load(const char *file, int *ox, int *oy) +{ + struct jpeg_decompress_struct cinfo; + struct jpeg_decompress_struct *ciptr = &cinfo; + struct r_jpeg_error_mgr emgr; + FILE *fh; + unsigned char *pic_buffer=NULL; + + if (!(fh = fopen(file, "rb"))) + return NULL; + + ciptr->err = jpeg_std_error(&emgr.pub); + emgr.pub.error_exit = jpeg_cb_error_exit; + if (setjmp(emgr.envbuffer) == 1) + { + jpeg_destroy_decompress(ciptr); + fclose(fh); + return NULL; + } + + jpeg_create_decompress(ciptr); + jpeg_stdio_src(ciptr, fh); + jpeg_read_header(ciptr, TRUE); + ciptr->out_color_space = JCS_RGB; + ciptr->scale_denom = 1; + + jpeg_start_decompress(ciptr); + + *ox=ciptr->output_width; + *oy=ciptr->output_height; + + if(ciptr->output_components == 3) + { + JSAMPLE *lb = (JSAMPLE *)(*ciptr->mem->alloc_small)((j_common_ptr) ciptr, JPOOL_PERMANENT, ciptr->output_width * ciptr->output_components); + pic_buffer = new unsigned char[ciptr->output_height * ciptr->output_width * ciptr->output_components]; + unsigned char *bp = pic_buffer; + + while (ciptr->output_scanline < ciptr->output_height) + { + jpeg_read_scanlines(ciptr, &lb, 1); + memcpy(bp, lb, ciptr->output_width * ciptr->output_components); + bp += ciptr->output_width * ciptr->output_components; + } + } + jpeg_finish_decompress(ciptr); + jpeg_destroy_decompress(ciptr); + fclose(fh); + return(pic_buffer); +} + + +static int jpeg_save(const char * filename, int ox, int oy, unsigned char *pic_buffer) +{ + struct jpeg_compress_struct cinfo; + struct jpeg_error_mgr jerr; + FILE * outfile; + JSAMPROW row_pointer[1]; + int row_stride; + + cinfo.err = jpeg_std_error(&jerr); + jpeg_create_compress(&cinfo); + + if ((outfile = fopen(filename, "wb")) == NULL) + { + eDebug("[Picload] jpeg can't open %s", filename); + return 1; + } + eDebug("[Picload] save Thumbnail... %s",filename); + + jpeg_stdio_dest(&cinfo, outfile); + + cinfo.image_width = ox; + cinfo.image_height = oy; + cinfo.input_components = 3; + cinfo.in_color_space = JCS_RGB; + jpeg_set_defaults(&cinfo); + jpeg_set_quality(&cinfo, 70, TRUE ); + jpeg_start_compress(&cinfo, TRUE); + row_stride = ox * 3; + while (cinfo.next_scanline < cinfo.image_height) + { + row_pointer[0] = & pic_buffer[cinfo.next_scanline * row_stride]; + (void) jpeg_write_scanlines(&cinfo, row_pointer, 1); + } + jpeg_finish_compress(&cinfo); + fclose(outfile); + jpeg_destroy_compress(&cinfo); + return 0; } //------------------------------------------------------------------- @@ -597,8 +449,9 @@ inline void m_rend_gif_decodecolormap(unsigned char *cmb, unsigned char *rgbb, C } } -static int gif_load(const char *filename, int *x, int *y) +static unsigned char *gif_load(const char *file, int *ox, int *oy) { + unsigned char *pic_buffer = NULL; int px, py, i, j, ibxs; unsigned char *fbptr; unsigned char *lb=NULL; @@ -610,9 +463,9 @@ static int gif_load(const char *filename, int *x, int *y) int cmaps; int extcode; - gft = DGifOpenFileName(filename); + gft = DGifOpenFileName(file); if (gft == NULL) - return 0; + return NULL; do { if (DGifGetRecordType(gft, &rt) == GIF_ERROR) @@ -622,8 +475,8 @@ static int gif_load(const char *filename, int *x, int *y) case IMAGE_DESC_RECORD_TYPE: if (DGifGetImageDesc(gft) == GIF_ERROR) goto ERROR_R; - *x = px = gft->Image.Width; - *y = py = gft->Image.Height; + *ox = px = gft->Image.Width; + *oy = py = gft->Image.Height; pic_buffer = new unsigned char[px * py * 3]; lb = (unsigned char *)malloc(px * 3); slb = (unsigned char *) malloc(px); @@ -685,239 +538,534 @@ static int gif_load(const char *filename, int *x, int *y) while (rt != TERMINATE_RECORD_TYPE); DGifCloseFile(gft); - return 1; + return(pic_buffer); ERROR_R: - eDebug("[GIF] Error"); + eDebug("[Picload] "); if (lb) free(lb); if (slb) free(slb); DGifCloseFile(gft); - return 0; + return NULL; } //--------------------------------------------------------------------------------------------- -PyObject *getExif(const char *filename) +ePicLoad::ePicLoad() + :msg_thread(this,1), msg_main(eApp,1) { - ePyObject list; - Cexif exif; - if(exif.DecodeExif(filename)) + CONNECT(msg_thread.recv_msg, ePicLoad::gotMessage); + CONNECT(msg_main.recv_msg, ePicLoad::gotMessage); + + threadrunning = false; + m_filepara = NULL; + m_conf.max_x = 0; + m_conf.max_y = 0; + m_conf.aspect_ratio = 1.066400; //4:3 + m_conf.usecache = false; + m_conf.resizetype = 1; + memset(m_conf.background,0x00,sizeof(m_conf.background)); + m_conf.thumbnailsize = 180; +} + +void ePicLoad::waitFinished() +{ + msg_thread.send(Message(Message::quit)); + kill(); +} + +ePicLoad::~ePicLoad() +{ + if (threadrunning) + waitFinished(); + if(m_filepara != NULL) + delete m_filepara; +} + +void ePicLoad::thread_finished() +{ + threadrunning=false; +} + +void ePicLoad::thread() +{ + hasStarted(); + threadrunning=true; + nice(4); + runLoop(); +} + +void ePicLoad::decodePic() +{ + eDebug("[Picload] decode picture... %s",m_filepara->file); + + switch(m_filepara->id) { - if(exif.m_exifinfo->IsExif) + case F_PNG: m_filepara->pic_buffer = png_load(m_filepara->file, &m_filepara->ox, &m_filepara->oy, &m_filepara->bypp); break; + case F_JPEG: m_filepara->pic_buffer = jpeg_load(m_filepara->file, &m_filepara->ox, &m_filepara->oy); break; + case F_BMP: m_filepara->pic_buffer = bmp_load(m_filepara->file, &m_filepara->ox, &m_filepara->oy); break; + case F_GIF: m_filepara->pic_buffer = gif_load(m_filepara->file, &m_filepara->ox, &m_filepara->oy); break; + } + + if(m_filepara->pic_buffer != NULL) + { + resizePic(); + } +} + +void ePicLoad::decodeThumb() +{ + eDebug("[Picload] get Thumbnail... %s",m_filepara->file); + + bool exif_thumbnail = false; + bool cachefile_found = false; + std::string cachefile = ""; + std::string cachedir = "/.Thumbnails"; + + if(m_filepara->id == F_JPEG) + { + Cexif *exif = new Cexif; + if(exif->DecodeExif(m_filepara->file, 1)) { - int pos=0; - char tmp[256]; - list = PyList_New(22); - PyList_SET_ITEM(list, pos++, PyString_FromString(exif.m_exifinfo->Version)); - PyList_SET_ITEM(list, pos++, PyString_FromString(exif.m_exifinfo->CameraMake)); - PyList_SET_ITEM(list, pos++, PyString_FromString(exif.m_exifinfo->CameraModel)); - PyList_SET_ITEM(list, pos++, PyString_FromString(exif.m_exifinfo->DateTime)); - PyList_SET_ITEM(list, pos++, PyString_FromString(exif.m_exifinfo->Comments)); - PyList_SET_ITEM(list, pos++, PyString_FromFormat("%d x %d", exif.m_exifinfo->Width, exif.m_exifinfo->Height)); - PyList_SET_ITEM(list, pos++, PyString_FromString(exif.m_exifinfo->Orientation)); - PyList_SET_ITEM(list, pos++, PyString_FromString(exif.m_exifinfo->MeteringMode)); - PyList_SET_ITEM(list, pos++, PyString_FromString(exif.m_exifinfo->ExposureProgram)); - PyList_SET_ITEM(list, pos++, PyString_FromString(exif.m_exifinfo->LightSource)); - PyList_SET_ITEM(list, pos++, PyString_FromString(exif.m_exifinfo->FlashUsed)); - PyList_SET_ITEM(list, pos++, PyString_FromFormat("%d", exif.m_exifinfo->CompressionLevel)); - PyList_SET_ITEM(list, pos++, PyString_FromFormat("%d", exif.m_exifinfo->ISOequivalent)); - sprintf(tmp, "%.2f", exif.m_exifinfo->Xresolution); - PyList_SET_ITEM(list, pos++, PyString_FromString(tmp)); - sprintf(tmp, "%.2f", exif.m_exifinfo->Yresolution); - PyList_SET_ITEM(list, pos++, PyString_FromString(tmp)); - PyList_SET_ITEM(list, pos++, PyString_FromString(exif.m_exifinfo->ResolutionUnit)); - sprintf(tmp, "%.2f", exif.m_exifinfo->Brightness); - PyList_SET_ITEM(list, pos++, PyString_FromString(tmp)); - sprintf(tmp, "%.5f sec.", exif.m_exifinfo->ExposureTime); - PyList_SET_ITEM(list, pos++, PyString_FromString(tmp)); - sprintf(tmp, "%.5f", exif.m_exifinfo->ExposureBias); - PyList_SET_ITEM(list, pos++, PyString_FromString(tmp)); - sprintf(tmp, "%.5f", exif.m_exifinfo->Distance); - PyList_SET_ITEM(list, pos++, PyString_FromString(tmp)); - sprintf(tmp, "%.5f", exif.m_exifinfo->CCDWidth); - PyList_SET_ITEM(list, pos++, PyString_FromString(tmp)); - sprintf(tmp, "%.2f", exif.m_exifinfo->ApertureFNumber); - PyList_SET_ITEM(list, pos++, PyString_FromString(tmp)); + if(exif->m_exifinfo->IsExif) + { + if(exif->m_exifinfo->Thumnailstate==2) + { + m_filepara->file = strdup(THUMBNAILTMPFILE); + exif_thumbnail = true; + eDebug("[Picload] Exif Thumbnail found"); + } + m_filepara->addExifInfo(exif->m_exifinfo->CameraMake); + m_filepara->addExifInfo(exif->m_exifinfo->CameraModel); + m_filepara->addExifInfo(exif->m_exifinfo->DateTime); + char buf[20]; + snprintf(buf, 20, "%d x %d", exif->m_exifinfo->Width, exif->m_exifinfo->Height); + m_filepara->addExifInfo(buf); + } + exif->ClearExif(); } - else + delete exif; + } + + if((! exif_thumbnail) && m_conf.usecache) + { + if(FILE *f=fopen(m_filepara->file, "rb")) { - list = PyList_New(1); - PyList_SET_ITEM(list, 0, PyString_FromString(exif.m_szLastError)); + int c; + int count = 1024*100; + unsigned long crc32 = 0; + char crcstr[9];*crcstr=0; + + while ((c=getc(f))!=EOF) + { + crc32 = crc32_table[((crc32) ^ (c)) & 0xFF] ^ ((crc32) >> 8); + if(--count < 0) break; + } + + fclose(f); + crc32 = ~crc32; + sprintf(crcstr, "%08lX", crc32); + + cachedir = m_filepara->file; + unsigned int pos = cachedir.find_last_of("/"); + if (pos != std::string::npos) + cachedir = cachedir.substr(0, pos) + "/.Thumbnails"; + + cachefile = cachedir + std::string("/pc_") + crcstr; + if(!access(cachefile.c_str(), R_OK)) + { + cachefile_found = true; + m_filepara->file = strdup(cachefile.c_str()); + m_filepara->id = F_JPEG; + eDebug("[Picload] Cache File found"); + } } - exif.ClearExif(); } - else + + switch(m_filepara->id) { - list = PyList_New(1); - PyList_SET_ITEM(list, 0, PyString_FromString(exif.m_szLastError)); + case F_PNG: m_filepara->pic_buffer = png_load(m_filepara->file, &m_filepara->ox, &m_filepara->oy, &m_filepara->bypp); break; + case F_JPEG: m_filepara->pic_buffer = jpeg_load(m_filepara->file, &m_filepara->ox, &m_filepara->oy); break; + case F_BMP: m_filepara->pic_buffer = bmp_load(m_filepara->file, &m_filepara->ox, &m_filepara->oy); break; + case F_GIF: m_filepara->pic_buffer = gif_load(m_filepara->file, &m_filepara->ox, &m_filepara->oy); break; } + + if(exif_thumbnail) + ::unlink(THUMBNAILTMPFILE); + + if(m_filepara->pic_buffer != NULL) + { + //save cachefile + if(m_conf.usecache && (! exif_thumbnail) && (! cachefile_found)) + { + if(access(cachedir.c_str(), R_OK)) + ::mkdir(cachedir.c_str(), 0755); + + //resize for Thumbnail + int imx, imy; + if (m_filepara->ox <= m_filepara->oy) + { + imy = m_conf.thumbnailsize; + imx = (int)( (m_conf.thumbnailsize * ((double)m_filepara->ox)) / ((double)m_filepara->oy) ); + } + else + { + imx = m_conf.thumbnailsize; + imy = (int)( (m_conf.thumbnailsize * ((double)m_filepara->oy)) / ((double)m_filepara->ox) ); + } - return list ? (PyObject*)list : (PyObject*)PyList_New(0); -} + m_filepara->pic_buffer = color_resize(m_filepara->pic_buffer, m_filepara->ox, m_filepara->oy, imx, imy, m_filepara->bypp); + m_filepara->ox = imx; + m_filepara->oy = imy; -//--------------------------------------------------------------------------------------------- -enum {F_NONE, F_PNG, F_JPEG, F_BMP, F_GIF}; + if(jpeg_save(cachefile.c_str(), m_filepara->ox, m_filepara->oy, m_filepara->pic_buffer)) + eDebug("[Picload] error saving cachefile"); + } + + resizePic(); + } +} -static int pic_id(const char *name) +void ePicLoad::resizePic() { - unsigned char id[10]; - int fd = open(name, O_RDONLY); - if (fd == -1) - return F_NONE; - read(fd, id, 10); - close(fd); + int imx, imy; - if(id[1] == 'P' && id[2] == 'N' && id[3] == 'G') - return F_PNG; - else if(id[6] == 'J' && id[7] == 'F' && id[8] == 'I' && id[9] == 'F') - return F_JPEG; - else if(id[0] == 0xff && id[1] == 0xd8 && id[2] == 0xff) - return F_JPEG; - else if(id[0] == 'B' && id[1] == 'M' ) - return F_BMP; - else if(id[0] == 'G' && id[1] == 'I' && id[2] == 'F') - return F_GIF; - return F_NONE; + if((m_conf.aspect_ratio * m_filepara->oy * m_filepara->max_x / m_filepara->ox) <= m_filepara->max_y) + { + imx = m_filepara->max_x; + imy = (int)(m_conf.aspect_ratio * m_filepara->oy * m_filepara->max_x / m_filepara->ox); + } + else + { + imx = (int)((1.0/m_conf.aspect_ratio) * m_filepara->ox * m_filepara->max_y / m_filepara->oy); + imy = m_filepara->max_y; + } + + if(m_conf.resizetype) + m_filepara->pic_buffer = color_resize(m_filepara->pic_buffer, m_filepara->ox, m_filepara->oy, imx, imy, m_filepara->bypp); + else + m_filepara->pic_buffer = simple_resize(m_filepara->pic_buffer, m_filepara->ox, m_filepara->oy, imx, imy, m_filepara->bypp); + + m_filepara->ox = imx; + m_filepara->oy = imy; } -int loadPic(ePtr &result, std::string filename, int w, int h, int aspect, int resize_mode, int rotate, int background, std::string cachefile, int thumbnail) +void ePicLoad::gotMessage(const Message &msg) { - result = 0; - int ox=0, oy=0, imx, imy; - pic_buffer=NULL; - bool cache=false; + switch (msg.type) + { + case Message::decode_Pic: + decodePic(); + msg_main.send(Message(Message::decode_finished)); + break; + case Message::decode_Thumb: + decodeThumb(); + msg_main.send(Message(Message::decode_finished)); + break; + case Message::quit: // called from decode thread + eDebug("[Picload] decode thread ... got quit msg"); + quit(0); + break; + case Message::decode_finished: // called from main thread + //eDebug("[Picload] decode finished... %s", m_filepara->file); + if(m_filepara->callback) + { + PictureData(m_filepara->picinfo.c_str()); + } + else + { + if(m_filepara != NULL) + { + delete m_filepara; + m_filepara = NULL; + } + } + break; + default: + eDebug("unhandled thread message"); + } +} - if(cachefile.length()) +int ePicLoad::startThread(int what, const char *file, int x, int y, bool async) +{ + if(async && threadrunning && m_filepara != NULL) { - if(png_load(cachefile.c_str(), &ox, &oy)) - eDebug("[CACHEPIC] x-size=%d, y-size=%d", ox, oy); + eDebug("[Picload] thread running"); + m_filepara->callback = false; + return 1; + } + + if(m_filepara != NULL) + { + delete m_filepara; + m_filepara = NULL; + } + + int file_id = -1; + unsigned char id[10]; + int fd = ::open(file, O_RDONLY); + if (fd == -1) return 1; + ::read(fd, id, 10); + ::close(fd); + + if(id[1] == 'P' && id[2] == 'N' && id[3] == 'G') file_id = F_PNG; + else if(id[6] == 'J' && id[7] == 'F' && id[8] == 'I' && id[9] == 'F') file_id = F_JPEG; + else if(id[0] == 0xff && id[1] == 0xd8 && id[2] == 0xff) file_id = F_JPEG; + else if(id[0] == 'B' && id[1] == 'M' ) file_id = F_BMP; + else if(id[0] == 'G' && id[1] == 'I' && id[2] == 'F') file_id = F_GIF; + + if(file_id < 0) + { + eDebug("[Picload] "); + return 1; } - if(pic_buffer==NULL) + m_filepara = new Cfilepara(file, file_id, getSize(file)); + x > 0 ? m_filepara->max_x = x : m_filepara->max_x = m_conf.max_x; + y > 0 ? m_filepara->max_y = y : m_filepara->max_y = m_conf.max_y; + + if(m_filepara->max_x <= 0 || m_filepara->max_y <= 0) { - switch(pic_id(filename.c_str())) - { - case F_PNG: png_load(filename.c_str(), &ox, &oy);break; - case F_JPEG: { - if (thumbnail) - jpeg_load_thumb(filename.c_str(), &ox, &oy); - else - jpeg_load(filename.c_str(), &ox, &oy); - pic_buffer = conv24to32(pic_buffer, ox*oy, 1); - break; } - case F_BMP: bmp_load(filename.c_str(), &ox, &oy);pic_buffer = conv24to32(pic_buffer, ox*oy, 1); break; - case F_GIF: gif_load(filename.c_str(), &ox, &oy);pic_buffer = conv24to32(pic_buffer, ox*oy, 1); break; - default: - eDebug("[PIC] "); - return 0; - } + delete m_filepara; + m_filepara = NULL; + eDebug("[Picload] "); + return 1; + } - if(pic_buffer==NULL) - return 0; + if (async) { + if(what==1) + msg_thread.send(Message(Message::decode_Pic)); + else + msg_thread.send(Message(Message::decode_Thumb)); + run(); + } + else if (what == 1) + decodePic(); + else + decodeThumb(); + return 0; +} - double aspect_ratio; - switch(aspect) - { - case 1: aspect_ratio = 1.778 / ((double)720/576); break; //16:9 - case 2: aspect_ratio = 1.600 / ((double)720/576); break; //16:10 - case 3: aspect_ratio = 1.250 / ((double)720/576); break; //5:4 - default: aspect_ratio = 1.333 / ((double)720/576); //4:3 - } +RESULT ePicLoad::startDecode(const char *file, int x, int y, bool async) +{ + return startThread(1, file, x, y, async); +} + +RESULT ePicLoad::getThumbnail(const char *file, int x, int y, bool async) +{ + return startThread(0, file, x, y, async); +} - if((aspect_ratio * oy * w / ox) <= h) +PyObject *ePicLoad::getInfo(const char *filename) +{ + ePyObject list; + + Cexif *exif = new Cexif; + if(exif->DecodeExif(filename)) + { + if(exif->m_exifinfo->IsExif) { - imx = w; - imy = (int)(aspect_ratio*oy*w/ox); + char tmp[256]; + int pos=0; + list = PyList_New(23); + PyList_SET_ITEM(list, pos++, PyString_FromString(filename)); + PyList_SET_ITEM(list, pos++, PyString_FromString(exif->m_exifinfo->Version)); + PyList_SET_ITEM(list, pos++, PyString_FromString(exif->m_exifinfo->CameraMake)); + PyList_SET_ITEM(list, pos++, PyString_FromString(exif->m_exifinfo->CameraModel)); + PyList_SET_ITEM(list, pos++, PyString_FromString(exif->m_exifinfo->DateTime)); + PyList_SET_ITEM(list, pos++, PyString_FromFormat("%d x %d", exif->m_exifinfo->Width, exif->m_exifinfo->Height)); + PyList_SET_ITEM(list, pos++, PyString_FromString(exif->m_exifinfo->FlashUsed)); + PyList_SET_ITEM(list, pos++, PyString_FromString(exif->m_exifinfo->Orientation)); + PyList_SET_ITEM(list, pos++, PyString_FromString(exif->m_exifinfo->Comments)); + PyList_SET_ITEM(list, pos++, PyString_FromString(exif->m_exifinfo->MeteringMode)); + PyList_SET_ITEM(list, pos++, PyString_FromString(exif->m_exifinfo->ExposureProgram)); + PyList_SET_ITEM(list, pos++, PyString_FromString(exif->m_exifinfo->LightSource)); + PyList_SET_ITEM(list, pos++, PyString_FromFormat("%d", exif->m_exifinfo->CompressionLevel)); + PyList_SET_ITEM(list, pos++, PyString_FromFormat("%d", exif->m_exifinfo->ISOequivalent)); + sprintf(tmp, "%.2f", exif->m_exifinfo->Xresolution); + PyList_SET_ITEM(list, pos++, PyString_FromString(tmp)); + sprintf(tmp, "%.2f", exif->m_exifinfo->Yresolution); + PyList_SET_ITEM(list, pos++, PyString_FromString(tmp)); + PyList_SET_ITEM(list, pos++, PyString_FromString(exif->m_exifinfo->ResolutionUnit)); + sprintf(tmp, "%.2f", exif->m_exifinfo->Brightness); + PyList_SET_ITEM(list, pos++, PyString_FromString(tmp)); + sprintf(tmp, "%.5f sec.", exif->m_exifinfo->ExposureTime); + PyList_SET_ITEM(list, pos++, PyString_FromString(tmp)); + sprintf(tmp, "%.5f", exif->m_exifinfo->ExposureBias); + PyList_SET_ITEM(list, pos++, PyString_FromString(tmp)); + sprintf(tmp, "%.5f", exif->m_exifinfo->Distance); + PyList_SET_ITEM(list, pos++, PyString_FromString(tmp)); + sprintf(tmp, "%.5f", exif->m_exifinfo->CCDWidth); + PyList_SET_ITEM(list, pos++, PyString_FromString(tmp)); + sprintf(tmp, "%.2f", exif->m_exifinfo->ApertureFNumber); + PyList_SET_ITEM(list, pos++, PyString_FromString(tmp)); } else { - imx = (int)((1.0/aspect_ratio)*ox*h/oy); - imy = h; + list = PyList_New(2); + PyList_SET_ITEM(list, 0, PyString_FromString(filename)); + PyList_SET_ITEM(list, 1, PyString_FromString(exif->m_szLastError)); } + exif->ClearExif(); + } + else + { + list = PyList_New(2); + PyList_SET_ITEM(list, 0, PyString_FromString(filename)); + PyList_SET_ITEM(list, 1, PyString_FromString(exif->m_szLastError)); + } + delete exif; - if(resize_mode) pic_buffer = color_resize(pic_buffer, ox, oy, imx, imy); - else pic_buffer = simple_resize(pic_buffer, ox, oy, imx, imy); + return list ? (PyObject*)list : (PyObject*)PyList_New(0); +} - ox = imx; - oy = imy; - } - else cache = true; +int ePicLoad::getData(ePtr &result) +{ + result = 0; + if(m_filepara->pic_buffer == NULL) return 0; - result=new gPixmap(eSize(w, h), 32); + if(m_filepara->bypp == 3) + { + m_filepara->pic_buffer = conv24to32(m_filepara->pic_buffer, m_filepara->ox * m_filepara->oy); + } + + result=new gPixmap(eSize(m_filepara->max_x, m_filepara->max_y), 32); gSurface *surface = result->surface; int a=0, b=0; int nc=0, oc=0; int o_y=0, u_y=0, v_x=0, h_x=0; - unsigned char clear[4] = {0x00,0x00,0x00,0x00}; - if(background) clear[3]=0xFF; - unsigned char *tmp_buffer=((unsigned char *)(surface->data)); - if(oy < h) + unsigned char *tmp_buffer=((unsigned char *)(surface->data)); + + if(m_filepara->oy < m_filepara->max_y) { - o_y=(h-oy)/2; - u_y=h-oy-o_y; + o_y = (m_filepara->max_y - m_filepara->oy) / 2; + u_y = m_filepara->max_y - m_filepara->oy - o_y; } - if(ox < w) + if(m_filepara->ox < m_filepara->max_x) { - v_x=(w-ox)/2; - h_x=w-ox-v_x; + v_x = (m_filepara->max_x - m_filepara->ox) / 2; + h_x = m_filepara->max_x - m_filepara->ox - v_x; } - //eDebug("o_y=%d u_y=%d v_x=%d h_x=%d", o_y, u_y, v_x, h_x); - - if(oy < h) - for(a=0; a<(o_y*ox); a++, nc+=4) + if(m_filepara->oy < m_filepara->max_y) + { + for(a=0; a<(o_y*m_filepara->ox); a++, nc+=4) { tmp_buffer=((unsigned char *)(surface->data)) + nc; - memcpy(tmp_buffer, clear, sizeof(clear)); + memcpy(tmp_buffer, m_conf.background, sizeof(m_conf.background)); } - - for(a=0; aoy; a++) { - if(ox < w) + if(m_filepara->ox < m_filepara->max_x) + { for(b=0; bdata)) + nc; - memcpy(tmp_buffer, clear, sizeof(clear)); + memcpy(tmp_buffer, m_conf.background, sizeof(m_conf.background)); } + } - for(b=0; b<(ox*4); b+=4, nc+=4) + for(b=0; b<(m_filepara->ox*4); b+=4, nc+=4) { tmp_buffer=((unsigned char *)(surface->data)) + nc; - tmp_buffer[2]=pic_buffer[oc++]; - tmp_buffer[1]=pic_buffer[oc++]; - tmp_buffer[0]=pic_buffer[oc++]; - tmp_buffer[3]=pic_buffer[oc++]; - + tmp_buffer[2] = m_filepara->pic_buffer[oc++]; + tmp_buffer[1] = m_filepara->pic_buffer[oc++]; + tmp_buffer[0] = m_filepara->pic_buffer[oc++]; + tmp_buffer[3] = m_filepara->pic_buffer[oc++]; } - if(ox < w) + if(m_filepara->ox < m_filepara->max_x) + { for(b=0; bdata)) + nc; - memcpy(tmp_buffer, clear, sizeof(clear)); + memcpy(tmp_buffer, m_conf.background, sizeof(m_conf.background)); } + } } - - if(oy < h) - for(a=0; a<(u_y*ox); a++, nc+=4) + + if(m_filepara->oy < m_filepara->max_y) + { + for(a=0; a<(u_y*m_filepara->ox); a++, nc+=4) { tmp_buffer=((unsigned char *)(surface->data)) + nc; - memcpy(tmp_buffer, clear, sizeof(clear)); + memcpy(tmp_buffer, m_conf.background, sizeof(m_conf.background)); } - - //eDebug("[PIC] buffer=%d, nc=%d oc=%d ox=%d, oy=%d",w*h*4, nc, oc, ox, oy); + } surface->clut.data=0; surface->clut.colors=0; surface->clut.start=0; + + delete m_filepara; + m_filepara = NULL; + + return 0; +} + +RESULT ePicLoad::setPara(PyObject *val) +{ + if (!PySequence_Check(val)) + return 0; + if (PySequence_Size(val) < 7) + return 0; + else { + ePyObject fast = PySequence_Fast(val, ""); + m_conf.max_x = PyInt_AsLong( PySequence_Fast_GET_ITEM(fast, 0)); + m_conf.max_y = PyInt_AsLong( PySequence_Fast_GET_ITEM(fast, 1)); + m_conf.aspect_ratio = (double)PyInt_AsLong( PySequence_Fast_GET_ITEM(fast, 2)) / PyInt_AsLong(PySequence_Fast_GET_ITEM(fast, 3)); + m_conf.usecache = PyInt_AsLong( PySequence_Fast_GET_ITEM(fast, 4)); + m_conf.resizetype = PyInt_AsLong( PySequence_Fast_GET_ITEM(fast, 5)); + const char *bg_str = PyString_AsString( PySequence_Fast_GET_ITEM(fast, 6)); - delete [] pic_buffer; + if(bg_str[0] == '#' && strlen(bg_str)==9) + { + int bg = strtoul(bg_str+1, NULL, 16); + m_conf.background[0] = bg&0xFF; //BB + m_conf.background[1] = (bg>>8)&0xFF; //GG + m_conf.background[2] = (bg>>16)&0xFF; //RR + m_conf.background[3] = bg>>24; //AA + } + 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]); + } + return 1; +} + +//------------------------------------------------------------------------------------ - if(cachefile.length() && !cache) +//for old plugins +SWIG_VOID(int) loadPic(ePtr &result, std::string filename, int x, int y, int aspect, int resize_mode, int rotate, int background, std::string cachefile) +{ + long asp1, asp2; + result = 0; + 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!"); + ePicLoad mPL; + + switch(aspect) { - savePNG( cachefile.c_str(), result); - eDebug("[SAVEPIC] x-size=%d, y-size=%d", ox, oy); + case 1: asp1 = 16*576, asp2 = 9*720; break; //16:9 + case 2: asp1 = 16*576, asp2 = 10*720; break; //16:10 + case 3: asp1 = 5*576, asp2 = 4*720; break; //5:4 + default: asp1 = 4*576, asp2 = 3*720; break; //4:3 } + ePyObject tuple = PyTuple_New(7); + PyTuple_SET_ITEM(tuple, 0, PyLong_FromLong(x)); + PyTuple_SET_ITEM(tuple, 1, PyLong_FromLong(y)); + PyTuple_SET_ITEM(tuple, 2, PyLong_FromLong(asp1)); + PyTuple_SET_ITEM(tuple, 3, PyLong_FromLong(asp2)); + PyTuple_SET_ITEM(tuple, 4, PyLong_FromLong(0)); + PyTuple_SET_ITEM(tuple, 5, PyLong_FromLong(resize_mode)); + if(background) + PyTuple_SET_ITEM(tuple, 6, PyString_FromString("#ff000000")); + else + PyTuple_SET_ITEM(tuple, 6, PyString_FromString("#00000000")); + + mPL.setPara(tuple); + + if(!mPL.startDecode(filename.c_str(), 0, 0, false)) + mPL.getData(result); + return 0; }