From: ghost Date: Sun, 16 Nov 2008 12:12:56 +0000 (+0100) Subject: work on asynchron pic loading... to get rid of spinning wheels X-Git-Url: http://code.vuplus.com/gitweb/?p=vuplus_dvbapp;a=commitdiff_plain;h=d732b430ccc1d1a78e666f16553b2e3c5dd131a8 work on asynchron pic loading... to get rid of spinning wheels --- diff --git a/lib/gdi/picexif.cpp b/lib/gdi/picexif.cpp index 844673c..f9e8055 100644 --- a/lib/gdi/picexif.cpp +++ b/lib/gdi/picexif.cpp @@ -75,7 +75,6 @@ Cexif::Cexif() Cexif::~Cexif() { - //ClearExif(); } void Cexif::ClearExif() @@ -89,7 +88,7 @@ void Cexif::ClearExif() } } -bool Cexif::DecodeExif(const char *filename) +bool Cexif::DecodeExif(const char *filename, int Thumb) { FILE * hFile = fopen(filename, "r"); if(!hFile) return false; @@ -98,6 +97,7 @@ bool Cexif::DecodeExif(const char *filename) m_exifinfo = new EXIFINFO; memset(m_exifinfo,0,sizeof(EXIFINFO)); freeinfo = true; + m_exifinfo->Thumnailstate = Thumb; m_szLastError[0]='\0'; ExifImageWidth = MotorolaOrder = SectionsRead=0; @@ -555,12 +555,16 @@ bool Cexif::ProcessExifDir(unsigned char * DirStart, unsigned char * OffsetBase, ProcessExifDir(SubdirStart, OffsetBase, ExifLength, m_exifinfo, LastExifRefdP); } - if (ThumbnailSize && ThumbnailOffset) + if (ThumbnailSize && ThumbnailOffset && m_exifinfo->Thumnailstate) { if (ThumbnailSize + ThumbnailOffset <= ExifLength) { - m_exifinfo->ThumbnailPointer = OffsetBase + ThumbnailOffset; - m_exifinfo->ThumbnailSize = ThumbnailSize; + if(FILE *tf = fopen(THUMBNAILTMPFILE, "w")) + { + fwrite( OffsetBase + ThumbnailOffset, ThumbnailSize, 1, tf); + fclose(tf); + m_exifinfo->Thumnailstate = 2; + } } } diff --git a/lib/gdi/picexif.h b/lib/gdi/picexif.h index cd321d7..bdd64b2 100644 --- a/lib/gdi/picexif.h +++ b/lib/gdi/picexif.h @@ -8,7 +8,7 @@ #define MAX_COMMENT 1000 #define MAX_SECTIONS 20 - +#define THUMBNAILTMPFILE "/tmp/.thumbcache" typedef struct tag_ExifInfo { char Version [5]; @@ -29,7 +29,7 @@ typedef struct tag_ExifInfo { float ExposureTime; float ExposureBias; float Distance; - float CCDWidth; //in milimeters + float CCDWidth; float FocalplaneXRes; float FocalplaneYRes; float FocalplaneUnits; @@ -40,9 +40,10 @@ typedef struct tag_ExifInfo { int ISOequivalent; int Process; int Orient; - unsigned char * ThumbnailPointer; - unsigned ThumbnailSize; + //unsigned char *ThumbnailPointer; + //unsigned ThumbnailSize; bool IsExif; + int Thumnailstate; } EXIFINFO; static const int BytesPerFormat[] = {0,1,1,2,4,8,1,1,2,4,8,4,8}; @@ -59,7 +60,7 @@ public: char m_szLastError[256]; Cexif(); ~Cexif(); - bool DecodeExif(const char *filename); + bool DecodeExif(const char *filename, int Thumb=0); void ClearExif(); protected: bool process_EXIF(unsigned char * CharBuf, unsigned int length); diff --git a/lib/gdi/picload.cpp b/lib/gdi/picload.cpp index 1f9bed4..2ef901f 100644 --- a/lib/gdi/picload.cpp +++ b/lib/gdi/picload.cpp @@ -1,38 +1,38 @@ #include // must be included before Python.h because of setjmp -#include -#include "picexif.h" -#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,28 +44,27 @@ 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) { unsigned char *cr, *p, *l; int i, j, k, ip; - cr = new unsigned char[dx * dy * 4]; + cr = new unsigned char[dx * dy * 3]; 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 * 3) { - p = orgin + (j * oy / dy * ox * 4); - for (i = 0, k = 0; i < dx; i++, k += 4) + p = orgin + (j * oy / dy * ox * 3); + for (i = 0, k = 0; i < dx; i++, k += 3) { - ip = i * ox / dx * 4; + ip = i * ox / dx * 3; l[k] = p[ip]; l[k+1] = p[ip + 1]; l[k+2] = p[ip + 2]; - l[k+3] = p[ip + 3]; } } delete [] orgin; @@ -76,18 +75,18 @@ static unsigned char *color_resize(unsigned char * orgin, int ox, int oy, int dx { 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]; + int sq, r, g, b; + cr = new unsigned char[dx * dy * 3]; 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 += 3) { xa = i * ox / dx; ya = j * oy / dy; @@ -97,269 +96,21 @@ static unsigned char *color_resize(unsigned char * orgin, int ox, int oy, int dx yb = (j + 1) * oy / dy; if (yb >= oy) yb = oy - 1; - for (l = ya, r = 0, g = 0, b = 0, a = 0, sq = 0; l <= yb; l++) + for (l = ya, r = 0, g = 0, b = 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) * 3); + for (k = xa; k <= xb; k++, q += 3, sq++) { - r += q[0]; g += q[1]; b += q[2]; a += q[3]; + r += q[0]; g += q[1]; b += q[2]; } } - 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; } } 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 +140,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 +171,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 +207,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,18 +243,18 @@ 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 const png_color_16 my_background = {0, 0, 0, 0, 0}; +//--------------------------------------------------------------------- +static unsigned char *png_load(const char *file, int *ox, int *oy) +{ + //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; @@ -513,17 +264,17 @@ static int png_load(const char *filename, int *x, int *y) 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); if (png_ptr == NULL) - return 0; + return NULL; 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; + return NULL; } if (setjmp(png_ptr->jmpbuf)) @@ -564,9 +315,9 @@ static int png_load(const char *filename, int *x, int *y) return 0; } - pic_buffer = new unsigned char[width * height * bpp]; - *x=width; - *y=height; + unsigned char *pic_buffer = new unsigned char[width * height * bpp]; + *ox=width; + *oy=height; for(pass = 0; pass < number_passes; pass++) { @@ -577,9 +328,113 @@ static int png_load(const char *filename, int *x, int *y) 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 +452,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 +466,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 +478,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 +541,477 @@ 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; +} + +ePicLoad::~ePicLoad() +{ + msg_thread.send(Message(Message::quit)); + kill(); + + if(m_filepara != NULL) + delete m_filepara; +} + + +void ePicLoad::thread() +{ + hasStarted(); + nice(4); + runLoop(); +} + +void ePicLoad::decodePic() +{ + eDebug("[Picload] decode picture... %s",m_filepara->file); + + switch(m_filepara->id) + { + case F_PNG: m_filepara->pic_buffer = png_load(m_filepara->file, &m_filepara->ox, &m_filepara->oy); 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) { - if(exif.m_exifinfo->IsExif) + 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); 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->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"); + } -static int pic_id(const char *name) + resizePic(); + } +} + +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((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); + else + m_filepara->pic_buffer = simple_resize(m_filepara->pic_buffer, m_filepara->ox, m_filepara->oy, 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; + 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); + threadrunning=false; + 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) +{ + if(threadrunning && m_filepara != NULL) + { + 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) { - if(png_load(cachefile.c_str(), &ox, &oy)) - eDebug("[CACHEPIC] x-size=%d, y-size=%d", ox, oy); + 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; + threadrunning=true; + if(what==1) + msg_thread.send(Message(Message::decode_Pic)); + else + msg_thread.send(Message(Message::decode_Thumb)); + run(); + 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) +{ + return startThread(1, file, x, y); +} + +RESULT ePicLoad::getThumbnail(const char *file, int x, int y) +{ + return startThread(0, file, x, y); +} - if((aspect_ratio * oy * w / ox) <= h) +RESULT ePicLoad::setPara(PyObject *val) +{ + if (!PyList_Check(val)) + return 0; + if (PyList_Size(val) < 6) + return 0; + + m_conf.max_x = PyInt_AsLong( PyList_GET_ITEM(val, 0)); + m_conf.max_y = PyInt_AsLong( PyList_GET_ITEM(val, 1)); + m_conf.aspect_ratio = PyFloat_AsDouble( PyList_GET_ITEM(val, 2)); + m_conf.usecache = PyInt_AsLong( PyList_GET_ITEM(val, 3)); + m_conf.resizetype = PyInt_AsLong( PyList_GET_ITEM(val, 4)); + const char *bg_str = PyString_AsString( PyList_GET_ITEM(val, 5)); + + 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; +} + +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) +{ + if(m_filepara->pic_buffer == NULL) return 0; + + m_filepara->pic_buffer = conv24to32(m_filepara->pic_buffer, m_filepara->ox * m_filepara->oy); - result=new gPixmap(eSize(w, h), 32); + 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 [] pic_buffer; - if(cachefile.length() && !cache) - { - savePNG( cachefile.c_str(), result); - eDebug("[SAVEPIC] x-size=%d, y-size=%d", ox, oy); - } + delete m_filepara; + m_filepara = NULL; return 0; } diff --git a/lib/gdi/picload.h b/lib/gdi/picload.h index 7bb9adf..a85567c 100644 --- a/lib/gdi/picload.h +++ b/lib/gdi/picload.h @@ -1,11 +1,102 @@ #ifndef __picload_h__ #define __picload_h__ -#include "Python.h" #include -#include +#include +#include +#include +#include -SWIG_VOID(int) loadPic(ePtr &SWIG_OUTPUT, std::string filename, int x, int y, int aspect, int resize_mode=0, int rotate=0, int background=0, std::string cachefile="", int thumbnail=0); -PyObject *getExif(const char *filename); +#ifndef SWIG +class Cfilepara +{ +public: + int max_x; + int max_y; + bool callback; + + const char *file; + int id; + int ox; + int oy; + unsigned char *pic_buffer; + std::string picinfo; + int test; + + Cfilepara(const char *mfile, int mid, std::string size) + { + file = strdup(mfile); + id = mid; + pic_buffer = NULL; + callback = true; + picinfo = mfile; + picinfo += + "\n" + size + "\n"; + } + + ~Cfilepara() + { + if(pic_buffer != NULL) delete pic_buffer; + picinfo.clear(); + } + + void addExifInfo(std::string val) { picinfo += val + "\n"; } +}; +#endif + +class ePicLoad: public eMainloop, public eThread, public Object, public iObject +{ + DECLARE_REF(ePicLoad); + + enum{ F_PNG, F_JPEG, F_BMP, F_GIF}; + + void decodePic(); + void decodeThumb(); + void resizePic(); + + Cfilepara *m_filepara; + bool threadrunning; + + struct PConf + { + int max_x; + int max_y; + double aspect_ratio; + unsigned char background[4]; + bool resizetype; + bool usecache; + int thumbnailsize; + int test; + } m_conf; + + struct Message + { + int type; + enum + { + decode_Pic, + decode_Thumb, + decode_finished, + quit + }; + Message(int type=0) + :type(type) {} + }; + eFixedMessagePump msg_thread, msg_main; + + void gotMessage(const Message &message); + void thread(); + int startThread(int what, const char *file, int x, int y); +public: + PSignal1 PictureData; + + ePicLoad(); + ~ePicLoad(); + + RESULT startDecode(const char *filename, int x=0, int y=0); + RESULT getThumbnail(const char *filename, int x=0, int y=0); + RESULT setPara(PyObject *val); + PyObject *getInfo(const char *filename); + SWIG_VOID(int) getData(ePtr &SWIG_OUTPUT); +}; #endif // __picload_h__ diff --git a/lib/python/Components/AVSwitch.py b/lib/python/Components/AVSwitch.py index 8f99b98..7ac2bb9 100644 --- a/lib/python/Components/AVSwitch.py +++ b/lib/python/Components/AVSwitch.py @@ -28,6 +28,21 @@ class AVSwitch: def setSystem(self, value): eAVSwitch.getInstance().setVideomode(value) + def getOutputAspect(self): + if valstr in ("4_3_letterbox", "4_3_panscan"): # 4:3 + return 1.333333333 + elif valstr == "16_9": # auto ... 4:3 or 16:9 + # TODO: here we must retrieve the current video aspect ratio... + # because the TV can run in 4:3 or in 16:9 mode.. (switched by wss or scart pin8) + # until we have done this we always return the scale value for 16:9!! + return 1.777777778 + elif valstr in ("16_9_always", "16_9_letterbox"): # 16:9 + return 1.777777778 + elif valstr in ("16_10_letterbox", "16_10_panscan"): # 16:10 + return 1.6 + print "unknown output aspect!" + return 1.0000 + def getAspectRatioSetting(self): valstr = config.av.aspectratio.value if valstr == "4_3_letterbox": diff --git a/lib/python/enigma_python.i b/lib/python/enigma_python.i index 7de05d2..8493637 100644 --- a/lib/python/enigma_python.i +++ b/lib/python/enigma_python.i @@ -141,6 +141,7 @@ typedef long time_t; %include // TODO: embed these... +%immutable ePicLoad::PictureData; %immutable eButton::selected; %immutable eInput::changed; %immutable eComponentScan::statusChanged;