From d732b430ccc1d1a78e666f16553b2e3c5dd131a8 Mon Sep 17 00:00:00 2001 From: ghost Date: Sun, 16 Nov 2008 13:12:56 +0100 Subject: work on asynchron pic loading... to get rid of spinning wheels --- lib/gdi/picload.cpp | 1028 ++++++++++++++++++++++++++++----------------------- 1 file changed, 561 insertions(+), 467 deletions(-) (limited to 'lib/gdi/picload.cpp') diff --git a/lib/gdi/picload.cpp b/lib/gdi/picload.cpp index 1f9bed48..2ef901f5 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; } -- cgit v1.2.3 From 9ccb92fb3eaca35ec60c1a596db9620f9f302044 Mon Sep 17 00:00:00 2001 From: ghost Date: Mon, 17 Nov 2008 21:17:34 +0100 Subject: more changes for async picture decode support --- lib/gdi/picload.cpp | 109 +++++++++++++++------ lib/gdi/picload.h | 5 + lib/python/Components/AVSwitch.py | 16 ++- .../SystemPlugins/Videomode/VideoHardware.py | 29 ++++++ 4 files changed, 125 insertions(+), 34 deletions(-) (limited to 'lib/gdi/picload.cpp') diff --git a/lib/gdi/picload.cpp b/lib/gdi/picload.cpp index 2ef901f5..b1dfd1a1 100644 --- a/lib/gdi/picload.cpp +++ b/lib/gdi/picload.cpp @@ -569,19 +569,29 @@ ePicLoad::ePicLoad() m_conf.thumbnailsize = 180; } -ePicLoad::~ePicLoad() +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(); } @@ -759,7 +769,6 @@ void ePicLoad::gotMessage(const Message &msg) 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()); @@ -824,7 +833,6 @@ int ePicLoad::startThread(int what, const char *file, int x, int y) return 1; } - threadrunning=true; if(what==1) msg_thread.send(Message(Message::decode_Pic)); else @@ -843,33 +851,6 @@ RESULT ePicLoad::getThumbnail(const char *file, int x, int y) return startThread(0, file, x, y); } -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; @@ -935,6 +916,7 @@ PyObject *ePicLoad::getInfo(const char *filename) int ePicLoad::getData(ePtr &result) { + result = 0; if(m_filepara->pic_buffer == NULL) return 0; m_filepara->pic_buffer = conv24to32(m_filepara->pic_buffer, m_filepara->ox * m_filepara->oy); @@ -1015,3 +997,70 @@ int ePicLoad::getData(ePtr &result) return 0; } + +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; +} + +//------------------------------------------------------------------------------------ + +//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) +{ + 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; + + 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 + } + + ePyObject list = PyList_New(6); + PyList_SET_ITEM(list, 0, PyLong_FromLong(x)); + PyList_SET_ITEM(list, 1, PyLong_FromLong(y)); + PyList_SET_ITEM(list, 2, PyFloat_FromDouble(aspect_ratio)); + PyList_SET_ITEM(list, 3, PyLong_FromLong(0)); + PyList_SET_ITEM(list, 4, PyLong_FromLong(resize_mode)); + if(background) + PyList_SET_ITEM(list, 5, PyString_FromString("#ff000000")); + else + PyList_SET_ITEM(list, 5, PyString_FromString("#00000000")); + + mPL.setPara(list); + + if(!mPL.startDecode(filename.c_str())) + { + mPL.waitFinished(); // this blocks until the thread is finished + mPL.getData(result); + } + + return 0; +} diff --git a/lib/gdi/picload.h b/lib/gdi/picload.h index a85567c0..6a0f70b9 100644 --- a/lib/gdi/picload.h +++ b/lib/gdi/picload.h @@ -86,7 +86,9 @@ class ePicLoad: public eMainloop, public eThread, public Object, public iObject void gotMessage(const Message &message); void thread(); int startThread(int what, const char *file, int x, int y); + void thread_finished(); public: + void waitFinished(); PSignal1 PictureData; ePicLoad(); @@ -99,4 +101,7 @@ public: SWIG_VOID(int) getData(ePtr &SWIG_OUTPUT); }; +//for old plugins +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=""); + #endif // __picload_h__ diff --git a/lib/python/Components/AVSwitch.py b/lib/python/Components/AVSwitch.py index 7ac2bb98..19aca24d 100644 --- a/lib/python/Components/AVSwitch.py +++ b/lib/python/Components/AVSwitch.py @@ -1,5 +1,5 @@ from config import config, ConfigSlider, ConfigSelection, ConfigYesNo, ConfigEnableDisable, ConfigSubsection, ConfigBoolean -from enigma import eAVSwitch +from enigma import eAVSwitch, getDesktop from SystemInfo import SystemInfo class AVSwitch: @@ -32,9 +32,12 @@ class AVSwitch: 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!! + try: + aspect_str = open("/proc/stb/vmpeg/0/aspect", "r").read() + if aspect_str == "1": # 4:3 + return 1.333333333 + except IOError: + pass return 1.777777778 elif valstr in ("16_9_always", "16_9_letterbox"): # 16:9 return 1.777777778 @@ -43,6 +46,11 @@ class AVSwitch: print "unknown output aspect!" return 1.0000 + def getFramebufferScale(self): + aspect = self.getOutputAspect() + fb_size = getDesktop(0).size() + return aspect / ((1.0 * fb_size.width()) / fb_size.height()) + def getAspectRatioSetting(self): valstr = config.av.aspectratio.value if valstr == "4_3_letterbox": diff --git a/lib/python/Plugins/SystemPlugins/Videomode/VideoHardware.py b/lib/python/Plugins/SystemPlugins/Videomode/VideoHardware.py index 2422475e..5e38f3e6 100644 --- a/lib/python/Plugins/SystemPlugins/Videomode/VideoHardware.py +++ b/lib/python/Plugins/SystemPlugins/Videomode/VideoHardware.py @@ -59,6 +59,34 @@ class VideoHardware: widescreen_modes = set(["720p", "1080i"]) + def getOutputAspect(self): + ret = 1.777777778 # 16:9 + port = config.av.videoport.value + if port not in config.av.videomode: + print "current port not available in getOutputAspect!!! force 16:9" + else: + mode = config.av.videomode[port].value + force_widescreen = self.isWidescreenMode(port, mode) + is_widescreen = force_widescreen or config.av.aspect.value in ["16_9", "16_10"] + is_auto = config.av.aspect.value == "auto" + if is_widescreen: + if force_widescreen: + pass + else: + aspect = {"16_9": "16:9", "16_10": "16:10"}[config.av.aspect.value] + if aspect == "16:10": + ret = 1.6 + elif is_auto: + try: + aspect_str = open("/proc/stb/vmpeg/0/aspect", "r").read() + if aspect_str == "1": # 4:3 + ret = 1.333333333 + except IOError: + pass + else: # 4:3 + ret = 1.333333333 + return ret + def __init__(self): self.last_modes_preferred = [ ] self.on_hotplug = CList() @@ -80,6 +108,7 @@ class VideoHardware: config.av.tvsystem.notifiers = [ ] config.av.wss.notifiers = [ ] AVSwitch.setInput = self.AVSwitchSetInput + AVSwitch.getOutputAspect = self.getOutputAspect config.av.aspect.addNotifier(self.updateAspect) config.av.wss.addNotifier(self.updateAspect) -- cgit v1.2.3 From 68687c79e44dbd66db07879bd25309f08e339ece Mon Sep 17 00:00:00 2001 From: ghost Date: Mon, 17 Nov 2008 23:12:48 +0100 Subject: picload.cpp: fix 32bpp pngs --- lib/gdi/picload.cpp | 65 ++++++++++++++++++++++++++++------------------------- 1 file changed, 34 insertions(+), 31 deletions(-) (limited to 'lib/gdi/picload.cpp') diff --git a/lib/gdi/picload.cpp b/lib/gdi/picload.cpp index b1dfd1a1..b9ca31aa 100644 --- a/lib/gdi/picload.cpp +++ b/lib/gdi/picload.cpp @@ -254,34 +254,33 @@ static unsigned char *bmp_load(const char *file, int *x, int *y) 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; + static const png_color_16 my_background = {0, 0, 0, 0, 0}; + 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(file, "rb"))) return NULL; + 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 NULL; - info_ptr = png_create_info_struct(png_ptr); + 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); + fclose(fh); return NULL; } if (setjmp(png_ptr->jmpbuf)) { 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); @@ -289,40 +288,44 @@ static unsigned char *png_load(const char *file, int *ox, int *oy) 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))) - png_set_expand(png_ptr); - if (bit_depth == 16) - png_set_strip_16(png_ptr); + if (color_type == PNG_COLOR_TYPE_PALETTE) + { + png_set_palette_to_rgb(png_ptr); + png_set_background(png_ptr, (png_color_16 *)&my_background, PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0); + } if (color_type == PNG_COLOR_TYPE_GRAY || color_type == PNG_COLOR_TYPE_GRAY_ALPHA) + { png_set_gray_to_rgb(png_ptr); + png_set_background(png_ptr, (png_color_16 *)&my_background, PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0); + } + if (color_type & PNG_COLOR_MASK_ALPHA) + png_set_strip_alpha(png_ptr); - number_passes = png_set_interlace_handling(png_ptr); - png_read_update_info(png_ptr, info_ptr); + if (bit_depth < 8) + png_set_packing(png_ptr); - int bpp = png_get_rowbytes(png_ptr, info_ptr)/width; - if ((bpp !=4) && (bpp !=3)) - { - eDebug("[PNG] Error processing"); - return 0; - } + if (bit_depth == 16) + png_set_strip_16(png_ptr); + + int number_passes = png_set_interlace_handling(png_ptr); + png_read_update_info(png_ptr, info_ptr); - if (width * height > 1000000) // 1000x1000 or equiv. + if (width * 3 != png_get_rowbytes(png_ptr, info_ptr)) { - 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; } - unsigned char *pic_buffer = new unsigned char[width * height * bpp]; + unsigned char *pic_buffer = new unsigned char[height * width * 3]; *ox=width; *oy=height; - 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 * 3) png_read_row(png_ptr, fbptr, NULL); } png_read_end(png_ptr, info_ptr); -- cgit v1.2.3 From 9ca172f45cc02fe5cb693e7d35aade7d2233d448 Mon Sep 17 00:00:00 2001 From: ghost Date: Mon, 17 Nov 2008 23:14:29 +0100 Subject: picload: more simple non async decode (deprecated) --- lib/gdi/picload.cpp | 86 ++++++++++++++++++++++++++++------------------------- lib/gdi/picload.h | 6 ++-- 2 files changed, 48 insertions(+), 44 deletions(-) (limited to 'lib/gdi/picload.cpp') diff --git a/lib/gdi/picload.cpp b/lib/gdi/picload.cpp index b9ca31aa..f67507ca 100644 --- a/lib/gdi/picload.cpp +++ b/lib/gdi/picload.cpp @@ -790,9 +790,9 @@ void ePicLoad::gotMessage(const Message &msg) } } -int ePicLoad::startThread(int what, const char *file, int x, int y) +int ePicLoad::startThread(int what, const char *file, int x, int y, bool async) { - if(threadrunning && m_filepara != NULL) + if(async && threadrunning && m_filepara != NULL) { eDebug("[Picload] thread running"); m_filepara->callback = false; @@ -836,22 +836,28 @@ int ePicLoad::startThread(int what, const char *file, int x, int y) return 1; } - if(what==1) - msg_thread.send(Message(Message::decode_Pic)); + 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 - msg_thread.send(Message(Message::decode_Thumb)); - run(); + decodeThumb(); return 0; } -RESULT ePicLoad::startDecode(const char *file, int x, int y) +RESULT ePicLoad::startDecode(const char *file, int x, int y, bool async) { - return startThread(1, file, x, y); + return startThread(1, file, x, y, async); } -RESULT ePicLoad::getThumbnail(const char *file, int x, int y) +RESULT ePicLoad::getThumbnail(const char *file, int x, int y, bool async) { - return startThread(0, file, x, y); + return startThread(0, file, x, y, async); } PyObject *ePicLoad::getInfo(const char *filename) @@ -1003,28 +1009,29 @@ int ePicLoad::getData(ePtr &result) RESULT ePicLoad::setPara(PyObject *val) { - if (!PyList_Check(val)) + if (!PySequence_Check(val)) return 0; - if (PyList_Size(val) < 6) + if (PySequence_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)); + else { + ePyObject fast = PySequence_Fast(val, ""); + m_conf.max_x = PyInt_AsLong( PySequence_Fast_GET_ITEM(val, 0)); + m_conf.max_y = PyInt_AsLong( PySequence_Fast_GET_ITEM(val, 1)); + m_conf.aspect_ratio = PyFloat_AsDouble( PySequence_Fast_GET_ITEM(val, 2)); + m_conf.usecache = PyInt_AsLong( PySequence_Fast_GET_ITEM(val, 3)); + m_conf.resizetype = PyInt_AsLong( PySequence_Fast_GET_ITEM(val, 4)); + const char *bg_str = PyString_AsString( PySequence_Fast_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 + 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]); } - - 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; } @@ -1046,24 +1053,21 @@ SWIG_VOID(int) loadPic(ePtr &result, std::string filename, int x, int y default: aspect_ratio = 1.333 / ((double)720/576); //4:3 } - ePyObject list = PyList_New(6); - PyList_SET_ITEM(list, 0, PyLong_FromLong(x)); - PyList_SET_ITEM(list, 1, PyLong_FromLong(y)); - PyList_SET_ITEM(list, 2, PyFloat_FromDouble(aspect_ratio)); - PyList_SET_ITEM(list, 3, PyLong_FromLong(0)); - PyList_SET_ITEM(list, 4, PyLong_FromLong(resize_mode)); + ePyObject tuple = PyTuple_New(6); + PyTuple_SET_ITEM(tuple, 0, PyLong_FromLong(x)); + PyTuple_SET_ITEM(tuple, 1, PyLong_FromLong(y)); + PyTuple_SET_ITEM(tuple, 2, PyFloat_FromDouble(aspect_ratio)); + PyTuple_SET_ITEM(tuple, 3, PyLong_FromLong(0)); + PyTuple_SET_ITEM(tuple, 4, PyLong_FromLong(resize_mode)); if(background) - PyList_SET_ITEM(list, 5, PyString_FromString("#ff000000")); + PyTuple_SET_ITEM(tuple, 5, PyString_FromString("#ff000000")); else - PyList_SET_ITEM(list, 5, PyString_FromString("#00000000")); + PyTuple_SET_ITEM(tuple, 5, PyString_FromString("#00000000")); - mPL.setPara(list); + mPL.setPara(tuple); - if(!mPL.startDecode(filename.c_str())) - { - mPL.waitFinished(); // this blocks until the thread is finished + if(!mPL.startDecode(filename.c_str(), 0, 0, false)) mPL.getData(result); - } return 0; } diff --git a/lib/gdi/picload.h b/lib/gdi/picload.h index 6a0f70b9..f64fd2f9 100644 --- a/lib/gdi/picload.h +++ b/lib/gdi/picload.h @@ -85,7 +85,7 @@ class ePicLoad: public eMainloop, public eThread, public Object, public iObject void gotMessage(const Message &message); void thread(); - int startThread(int what, const char *file, int x, int y); + int startThread(int what, const char *file, int x, int y, bool async=true); void thread_finished(); public: void waitFinished(); @@ -94,8 +94,8 @@ public: 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 startDecode(const char *filename, int x=0, int y=0, bool async=true); + RESULT getThumbnail(const char *filename, int x=0, int y=0, bool async=true); RESULT setPara(PyObject *val); PyObject *getInfo(const char *filename); SWIG_VOID(int) getData(ePtr &SWIG_OUTPUT); -- cgit v1.2.3 From 5aa89f34249397330995cc0ab1e080c1f567e174 Mon Sep 17 00:00:00 2001 From: ghost Date: Mon, 17 Nov 2008 23:34:41 +0100 Subject: get rid of some floating point values --- lib/gdi/picload.cpp | 35 +++++++++++----------- lib/python/Components/AVSwitch.py | 14 ++++----- .../Plugins/Extensions/PicturePlayer/plugin.py | 14 +++++---- .../SystemPlugins/Videomode/VideoHardware.py | 8 ++--- 4 files changed, 36 insertions(+), 35 deletions(-) (limited to 'lib/gdi/picload.cpp') diff --git a/lib/gdi/picload.cpp b/lib/gdi/picload.cpp index f67507ca..375f33fb 100644 --- a/lib/gdi/picload.cpp +++ b/lib/gdi/picload.cpp @@ -1011,16 +1011,16 @@ RESULT ePicLoad::setPara(PyObject *val) { if (!PySequence_Check(val)) return 0; - if (PySequence_Size(val) < 6) + if (PySequence_Size(val) < 7) return 0; else { ePyObject fast = PySequence_Fast(val, ""); m_conf.max_x = PyInt_AsLong( PySequence_Fast_GET_ITEM(val, 0)); m_conf.max_y = PyInt_AsLong( PySequence_Fast_GET_ITEM(val, 1)); - m_conf.aspect_ratio = PyFloat_AsDouble( PySequence_Fast_GET_ITEM(val, 2)); - m_conf.usecache = PyInt_AsLong( PySequence_Fast_GET_ITEM(val, 3)); - m_conf.resizetype = PyInt_AsLong( PySequence_Fast_GET_ITEM(val, 4)); - const char *bg_str = PyString_AsString( PySequence_Fast_GET_ITEM(val, 5)); + m_conf.aspect_ratio = (double)PyInt_AsLong( PySequence_Fast_GET_ITEM(val, 2)) / PyInt_AsLong(PySequence_Fast_GET_ITEM(val, 3)); + m_conf.usecache = PyInt_AsLong( PySequence_Fast_GET_ITEM(val, 4)); + m_conf.resizetype = PyInt_AsLong( PySequence_Fast_GET_ITEM(val, 5)); + const char *bg_str = PyString_AsString( PySequence_Fast_GET_ITEM(val, 6)); if(bg_str[0] == '#' && strlen(bg_str)==9) { @@ -1040,29 +1040,30 @@ RESULT ePicLoad::setPara(PyObject *val) //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; - 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 + 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(6); + + 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, PyFloat_FromDouble(aspect_ratio)); - PyTuple_SET_ITEM(tuple, 3, PyLong_FromLong(0)); - PyTuple_SET_ITEM(tuple, 4, PyLong_FromLong(resize_mode)); + 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, 5, PyString_FromString("#ff000000")); + PyTuple_SET_ITEM(tuple, 6, PyString_FromString("#ff000000")); else - PyTuple_SET_ITEM(tuple, 5, PyString_FromString("#00000000")); + PyTuple_SET_ITEM(tuple, 6, PyString_FromString("#00000000")); mPL.setPara(tuple); diff --git a/lib/python/Components/AVSwitch.py b/lib/python/Components/AVSwitch.py index 19aca24d..00350cbb 100644 --- a/lib/python/Components/AVSwitch.py +++ b/lib/python/Components/AVSwitch.py @@ -30,26 +30,24 @@ class AVSwitch: def getOutputAspect(self): if valstr in ("4_3_letterbox", "4_3_panscan"): # 4:3 - return 1.333333333 + return (4,3) elif valstr == "16_9": # auto ... 4:3 or 16:9 try: aspect_str = open("/proc/stb/vmpeg/0/aspect", "r").read() if aspect_str == "1": # 4:3 - return 1.333333333 + return (4,3) except IOError: pass - return 1.777777778 elif valstr in ("16_9_always", "16_9_letterbox"): # 16:9 - return 1.777777778 + pass elif valstr in ("16_10_letterbox", "16_10_panscan"): # 16:10 - return 1.6 - print "unknown output aspect!" - return 1.0000 + return (16,10) + return (16,9) def getFramebufferScale(self): aspect = self.getOutputAspect() fb_size = getDesktop(0).size() - return aspect / ((1.0 * fb_size.width()) / fb_size.height()) + return (aspect[0] * fb_size.height(), aspect[1] * fb_size.width()) def getAspectRatioSetting(self): valstr = config.av.aspectratio.value diff --git a/lib/python/Plugins/Extensions/PicturePlayer/plugin.py b/lib/python/Plugins/Extensions/PicturePlayer/plugin.py index 7d62d2be..0cdab563 100644 --- a/lib/python/Plugins/Extensions/PicturePlayer/plugin.py +++ b/lib/python/Plugins/Extensions/PicturePlayer/plugin.py @@ -15,7 +15,7 @@ from Components.ConfigList import ConfigList from Components.config import config, ConfigSubsection, ConfigInteger, ConfigSelection, ConfigText, ConfigEnableDisable, KEY_LEFT, KEY_RIGHT, KEY_0, getConfigListEntry -def getAspectforPic(): +def getScale(): return AVSwitch().getFramebufferScale() config.pic = ConfigSubsection() @@ -119,8 +119,9 @@ class picshow(Screen): self.session.openWithCallback(self.callbackView, Pic_Full_View, self.filelist.getFileList(), self.filelist.getSelectionIndex(), self.filelist.getCurrentDirectory()) def setConf(self): + sc = getScale() #0=Width 1=Height 2=Aspect 3=use_cache 4=resize_type 5=Background(#AARRGGBB) - self.picload.setPara([self["thn"].instance.size().width(), self["thn"].instance.size().height(), getAspectforPic(), config.pic.cache.value, int(config.pic.resize.value), "#00000000"]) + self.picload.setPara((self["thn"].instance.size().width(), self["thn"].instance.size().height(), sc[0], sc[1], config.pic.cache.value, int(config.pic.resize.value), "#00000000")) def callbackView(self, val=0): if val > 0: @@ -311,10 +312,10 @@ class Pic_Thumb(Screen): self.ThumbTimer.callback.append(self.showPic) def setPicloadConf(self): - self.picload.setPara([self["thumb0"].instance.size().width(), self["thumb0"].instance.size().height(), getAspectforPic(), config.pic.cache.value, int(config.pic.resize.value), self.color]) + sc = getScale() + self.picload.setPara([self["thumb0"].instance.size().width(), self["thumb0"].instance.size().height(), sc[0], sc[1], config.pic.cache.value, int(config.pic.resize.value), self.color]) self.paintFrame() - - + def paintFrame(self): #print "index=" + str(self.index) if self.maxentry < self.index or self.index < 0: @@ -468,7 +469,8 @@ class Pic_Full_View(Screen): self.onLayoutFinish.append(self.setPicloadConf) def setPicloadConf(self): - self.picload.setPara([self["pic"].instance.size().width(), self["pic"].instance.size().height(), getAspectforPic(), 0, int(config.pic.resize.value), self.bgcolor]) + sc = getScale() + self.picload.setPara([self["pic"].instance.size().width(), self["pic"].instance.size().height(), sc[0], sc[1], 0, int(config.pic.resize.value), self.bgcolor]) self["play_icon"].hide() if config.pic.infoline.value == False: diff --git a/lib/python/Plugins/SystemPlugins/Videomode/VideoHardware.py b/lib/python/Plugins/SystemPlugins/Videomode/VideoHardware.py index 5e38f3e6..02fdf9a5 100644 --- a/lib/python/Plugins/SystemPlugins/Videomode/VideoHardware.py +++ b/lib/python/Plugins/SystemPlugins/Videomode/VideoHardware.py @@ -60,7 +60,7 @@ class VideoHardware: widescreen_modes = set(["720p", "1080i"]) def getOutputAspect(self): - ret = 1.777777778 # 16:9 + ret = (16,9) port = config.av.videoport.value if port not in config.av.videomode: print "current port not available in getOutputAspect!!! force 16:9" @@ -75,16 +75,16 @@ class VideoHardware: else: aspect = {"16_9": "16:9", "16_10": "16:10"}[config.av.aspect.value] if aspect == "16:10": - ret = 1.6 + ret = (16,10) elif is_auto: try: aspect_str = open("/proc/stb/vmpeg/0/aspect", "r").read() if aspect_str == "1": # 4:3 - ret = 1.333333333 + ret = (4,3) except IOError: pass else: # 4:3 - ret = 1.333333333 + ret = (4,3) return ret def __init__(self): -- cgit v1.2.3 From 1d042d155d0f33d2777e47da082b24b49a503491 Mon Sep 17 00:00:00 2001 From: ghost Date: Tue, 18 Nov 2008 15:44:31 +0100 Subject: fix typos --- lib/gdi/picload.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'lib/gdi/picload.cpp') diff --git a/lib/gdi/picload.cpp b/lib/gdi/picload.cpp index 375f33fb..0fafeabd 100644 --- a/lib/gdi/picload.cpp +++ b/lib/gdi/picload.cpp @@ -1015,12 +1015,12 @@ RESULT ePicLoad::setPara(PyObject *val) return 0; else { ePyObject fast = PySequence_Fast(val, ""); - m_conf.max_x = PyInt_AsLong( PySequence_Fast_GET_ITEM(val, 0)); - m_conf.max_y = PyInt_AsLong( PySequence_Fast_GET_ITEM(val, 1)); - m_conf.aspect_ratio = (double)PyInt_AsLong( PySequence_Fast_GET_ITEM(val, 2)) / PyInt_AsLong(PySequence_Fast_GET_ITEM(val, 3)); - m_conf.usecache = PyInt_AsLong( PySequence_Fast_GET_ITEM(val, 4)); - m_conf.resizetype = PyInt_AsLong( PySequence_Fast_GET_ITEM(val, 5)); - const char *bg_str = PyString_AsString( PySequence_Fast_GET_ITEM(val, 6)); + 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)); if(bg_str[0] == '#' && strlen(bg_str)==9) { -- cgit v1.2.3 From 3c31c5e7adaba2190409c39547ae4052ce5d83eb Mon Sep 17 00:00:00 2001 From: ghost Date: Thu, 20 Nov 2008 01:15:26 +0100 Subject: fix alpha channel for 1 or 2 bit pngs --- lib/gdi/picload.cpp | 20 ++++---------------- 1 file changed, 4 insertions(+), 16 deletions(-) (limited to 'lib/gdi/picload.cpp') diff --git a/lib/gdi/picload.cpp b/lib/gdi/picload.cpp index 0fafeabd..c162f89d 100644 --- a/lib/gdi/picload.cpp +++ b/lib/gdi/picload.cpp @@ -288,24 +288,12 @@ static unsigned char *png_load(const char *file, int *ox, int *oy) 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) - { - png_set_palette_to_rgb(png_ptr); - png_set_background(png_ptr, (png_color_16 *)&my_background, PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0); - } - if (color_type == PNG_COLOR_TYPE_GRAY || color_type == PNG_COLOR_TYPE_GRAY_ALPHA) - { - png_set_gray_to_rgb(png_ptr); - png_set_background(png_ptr, (png_color_16 *)&my_background, PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0); - } - if (color_type & PNG_COLOR_MASK_ALPHA) - png_set_strip_alpha(png_ptr); - - if (bit_depth < 8) - png_set_packing(png_ptr); - + 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); int number_passes = png_set_interlace_handling(png_ptr); png_read_update_info(png_ptr, info_ptr); -- cgit v1.2.3