From: Felix Domke Date: Tue, 18 Nov 2008 12:28:27 +0000 (+0100) Subject: Merge branch 'master' of git.opendreambox.org:/git/enigma2 X-Git-Url: http://code.vuplus.com/gitweb/?p=vuplus_dvbapp;a=commitdiff_plain;h=09565fe7720e8e042712b42a9dc7aac2949130cb;hp=71c070aafe23537ee96a68dbff46246d44476869 Merge branch 'master' of git.opendreambox.org:/git/enigma2 --- diff --git a/lib/dvb/db.cpp b/lib/dvb/db.cpp index 1c33203..4419158 100644 --- a/lib/dvb/db.cpp +++ b/lib/dvb/db.cpp @@ -497,7 +497,7 @@ void eDVBDB::saveServicelist(const char *file) { if (sat.system == eDVBFrontendParametersSatellite::System::DVB_S2) { - fprintf(f, "\ts %d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d", + fprintf(f, "\ts %d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d\n", sat.frequency, sat.symbol_rate, sat.polarisation, sat.fec, sat.orbital_position > 1800 ? sat.orbital_position - 3600 : sat.orbital_position, 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..375f33f 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,45 +243,44 @@ static int bmp_load(const char *filename, int *x, int *y) break; } default: - return 0; + return NULL; } close(fd); - return 1; + return(pic_buffer); } -//--------------------------------------------------------------------------------------------- -static int png_load(const char *filename, int *x, int *y) +//--------------------------------------------------------------------- + +static unsigned char *png_load(const char *file, int *ox, int *oy) { static const png_color_16 my_background = {0, 0, 0, 0, 0}; - png_structp png_ptr; - png_infop info_ptr; png_uint_32 width, height; unsigned int i; int bit_depth, color_type, interlace_type; - int number_passes, pass; - png_byte * fbptr; - FILE * fh; + png_byte *fbptr; + FILE *fh; - if (!(fh = fopen(filename, "rb"))) return 0; + if (!(fh = fopen(file, "rb"))) + return NULL; - png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); + png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); if (png_ptr == NULL) - return 0; - info_ptr = png_create_info_struct(png_ptr); + return NULL; + png_infop info_ptr = png_create_info_struct(png_ptr); if (info_ptr == NULL) { png_destroy_read_struct(&png_ptr, (png_infopp)NULL, (png_infopp)NULL); - fclose(fh); - return 0; + fclose(fh); + return NULL; } if (setjmp(png_ptr->jmpbuf)) { png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL); - fclose(fh); - return 0; + fclose(fh); + return NULL; } png_init_io(png_ptr, fh); @@ -538,48 +288,156 @@ static int png_load(const char *filename, int *x, int *y) png_read_info(png_ptr, info_ptr); png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, &interlace_type, NULL, NULL); - if ((color_type == PNG_COLOR_TYPE_PALETTE)||(color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8)||(png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS))) - 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); - if (width * height > 1000000) // 1000x1000 or equiv. + int number_passes = png_set_interlace_handling(png_ptr); + png_read_update_info(png_ptr, info_ptr); + + 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; } - pic_buffer = new unsigned char[width * height * bpp]; - *x=width; - *y=height; + 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); 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 +455,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 +469,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 +481,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 +544,531 @@ static int gif_load(const char *filename, int *x, int *y) while (rt != TERMINATE_RECORD_TYPE); DGifCloseFile(gft); - return 1; + return(pic_buffer); ERROR_R: - eDebug("[GIF] Error"); + eDebug("[Picload] "); if (lb) free(lb); if (slb) free(slb); DGifCloseFile(gft); - return 0; + return NULL; } //--------------------------------------------------------------------------------------------- -PyObject *getExif(const char *filename) +ePicLoad::ePicLoad() + :msg_thread(this,1), msg_main(eApp,1) { - ePyObject list; - Cexif exif; - if(exif.DecodeExif(filename)) + CONNECT(msg_thread.recv_msg, ePicLoad::gotMessage); + CONNECT(msg_main.recv_msg, ePicLoad::gotMessage); + + threadrunning = false; + m_filepara = NULL; + m_conf.max_x = 0; + m_conf.max_y = 0; + m_conf.aspect_ratio = 1.066400; //4:3 + m_conf.usecache = false; + m_conf.resizetype = 1; + memset(m_conf.background,0x00,sizeof(m_conf.background)); + m_conf.thumbnailsize = 180; +} + +void ePicLoad::waitFinished() +{ + msg_thread.send(Message(Message::quit)); + kill(); +} + +ePicLoad::~ePicLoad() +{ + if (threadrunning) + waitFinished(); + if(m_filepara != NULL) + delete m_filepara; +} + +void ePicLoad::thread_finished() +{ + threadrunning=false; +} + +void ePicLoad::thread() +{ + hasStarted(); + threadrunning=true; + nice(4); + runLoop(); +} + +void ePicLoad::decodePic() +{ + eDebug("[Picload] decode picture... %s",m_filepara->file); + + switch(m_filepara->id) + { + 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"); + } + + resizePic(); + } +} -static int pic_id(const char *name) +void ePicLoad::resizePic() { - unsigned char id[10]; - int fd = open(name, O_RDONLY); - if (fd == -1) - return F_NONE; - read(fd, id, 10); - close(fd); + int imx, imy; - if(id[1] == 'P' && id[2] == 'N' && id[3] == 'G') - return F_PNG; - else if(id[6] == 'J' && id[7] == 'F' && id[8] == 'I' && id[9] == 'F') - return F_JPEG; - else if(id[0] == 0xff && id[1] == 0xd8 && id[2] == 0xff) - return F_JPEG; - else if(id[0] == 'B' && id[1] == 'M' ) - return F_BMP; - else if(id[0] == 'G' && id[1] == 'I' && id[2] == 'F') - return F_GIF; - return F_NONE; + if((m_conf.aspect_ratio * m_filepara->oy * m_filepara->max_x / m_filepara->ox) <= m_filepara->max_y) + { + imx = m_filepara->max_x; + imy = (int)(m_conf.aspect_ratio * m_filepara->oy * m_filepara->max_x / m_filepara->ox); + } + else + { + imx = (int)((1.0/m_conf.aspect_ratio) * m_filepara->ox * m_filepara->max_y / m_filepara->oy); + imy = m_filepara->max_y; + } + + if(m_conf.resizetype) + m_filepara->pic_buffer = color_resize(m_filepara->pic_buffer, m_filepara->ox, m_filepara->oy, imx, imy); + else + m_filepara->pic_buffer = simple_resize(m_filepara->pic_buffer, m_filepara->ox, m_filepara->oy, imx, imy); + + m_filepara->ox = imx; + m_filepara->oy = imy; } -int loadPic(ePtr &result, std::string filename, int w, int h, int aspect, int resize_mode, int rotate, int background, std::string cachefile, int thumbnail) +void ePicLoad::gotMessage(const Message &msg) { - result = 0; - int ox=0, oy=0, imx, imy; - pic_buffer=NULL; - bool cache=false; + switch (msg.type) + { + case Message::decode_Pic: + decodePic(); + msg_main.send(Message(Message::decode_finished)); + break; + case Message::decode_Thumb: + decodeThumb(); + msg_main.send(Message(Message::decode_finished)); + break; + case Message::quit: // called from decode thread + eDebug("[Picload] decode thread ... got quit msg"); + quit(0); + break; + case Message::decode_finished: // called from main thread + //eDebug("[Picload] decode finished... %s", m_filepara->file); + if(m_filepara->callback) + { + PictureData(m_filepara->picinfo.c_str()); + } + else + { + if(m_filepara != NULL) + { + delete m_filepara; + m_filepara = NULL; + } + } + break; + default: + eDebug("unhandled thread message"); + } +} - if(cachefile.length()) +int ePicLoad::startThread(int what, const char *file, int x, int y, bool async) +{ + if(async && threadrunning && m_filepara != NULL) { - if(png_load(cachefile.c_str(), &ox, &oy)) - eDebug("[CACHEPIC] x-size=%d, y-size=%d", ox, oy); + eDebug("[Picload] thread running"); + m_filepara->callback = false; + return 1; + } + + if(m_filepara != NULL) + { + delete m_filepara; + m_filepara = NULL; + } + + int file_id = -1; + unsigned char id[10]; + int fd = ::open(file, O_RDONLY); + if (fd == -1) return 1; + ::read(fd, id, 10); + ::close(fd); + + if(id[1] == 'P' && id[2] == 'N' && id[3] == 'G') file_id = F_PNG; + else if(id[6] == 'J' && id[7] == 'F' && id[8] == 'I' && id[9] == 'F') file_id = F_JPEG; + else if(id[0] == 0xff && id[1] == 0xd8 && id[2] == 0xff) file_id = F_JPEG; + else if(id[0] == 'B' && id[1] == 'M' ) file_id = F_BMP; + else if(id[0] == 'G' && id[1] == 'I' && id[2] == 'F') file_id = F_GIF; + + if(file_id < 0) + { + eDebug("[Picload] "); + return 1; } - if(pic_buffer==NULL) + m_filepara = new Cfilepara(file, file_id, getSize(file)); + x > 0 ? m_filepara->max_x = x : m_filepara->max_x = m_conf.max_x; + y > 0 ? m_filepara->max_y = y : m_filepara->max_y = m_conf.max_y; + + if(m_filepara->max_x <= 0 || m_filepara->max_y <= 0) { - switch(pic_id(filename.c_str())) - { - case F_PNG: png_load(filename.c_str(), &ox, &oy);break; - case F_JPEG: { - if (thumbnail) - jpeg_load_thumb(filename.c_str(), &ox, &oy); - else - jpeg_load(filename.c_str(), &ox, &oy); - pic_buffer = conv24to32(pic_buffer, ox*oy, 1); - break; } - case F_BMP: bmp_load(filename.c_str(), &ox, &oy);pic_buffer = conv24to32(pic_buffer, ox*oy, 1); break; - case F_GIF: gif_load(filename.c_str(), &ox, &oy);pic_buffer = conv24to32(pic_buffer, ox*oy, 1); break; - default: - eDebug("[PIC] "); - return 0; - } + delete m_filepara; + m_filepara = NULL; + eDebug("[Picload] "); + return 1; + } - if(pic_buffer==NULL) - return 0; + if (async) { + if(what==1) + msg_thread.send(Message(Message::decode_Pic)); + else + msg_thread.send(Message(Message::decode_Thumb)); + run(); + } + else if (what == 1) + decodePic(); + else + decodeThumb(); + return 0; +} - double aspect_ratio; - switch(aspect) - { - case 1: aspect_ratio = 1.778 / ((double)720/576); break; //16:9 - case 2: aspect_ratio = 1.600 / ((double)720/576); break; //16:10 - case 3: aspect_ratio = 1.250 / ((double)720/576); break; //5:4 - default: aspect_ratio = 1.333 / ((double)720/576); //4:3 - } +RESULT ePicLoad::startDecode(const char *file, int x, int y, bool async) +{ + return startThread(1, file, x, y, async); +} - if((aspect_ratio * oy * w / ox) <= h) +RESULT ePicLoad::getThumbnail(const char *file, int x, int y, bool async) +{ + return startThread(0, file, x, y, async); +} + +PyObject *ePicLoad::getInfo(const char *filename) +{ + ePyObject list; + + Cexif *exif = new Cexif; + if(exif->DecodeExif(filename)) + { + if(exif->m_exifinfo->IsExif) { - imx = w; - imy = (int)(aspect_ratio*oy*w/ox); + char tmp[256]; + int pos=0; + list = PyList_New(23); + PyList_SET_ITEM(list, pos++, PyString_FromString(filename)); + PyList_SET_ITEM(list, pos++, PyString_FromString(exif->m_exifinfo->Version)); + PyList_SET_ITEM(list, pos++, PyString_FromString(exif->m_exifinfo->CameraMake)); + PyList_SET_ITEM(list, pos++, PyString_FromString(exif->m_exifinfo->CameraModel)); + PyList_SET_ITEM(list, pos++, PyString_FromString(exif->m_exifinfo->DateTime)); + PyList_SET_ITEM(list, pos++, PyString_FromFormat("%d x %d", exif->m_exifinfo->Width, exif->m_exifinfo->Height)); + PyList_SET_ITEM(list, pos++, PyString_FromString(exif->m_exifinfo->FlashUsed)); + PyList_SET_ITEM(list, pos++, PyString_FromString(exif->m_exifinfo->Orientation)); + PyList_SET_ITEM(list, pos++, PyString_FromString(exif->m_exifinfo->Comments)); + PyList_SET_ITEM(list, pos++, PyString_FromString(exif->m_exifinfo->MeteringMode)); + PyList_SET_ITEM(list, pos++, PyString_FromString(exif->m_exifinfo->ExposureProgram)); + PyList_SET_ITEM(list, pos++, PyString_FromString(exif->m_exifinfo->LightSource)); + PyList_SET_ITEM(list, pos++, PyString_FromFormat("%d", exif->m_exifinfo->CompressionLevel)); + PyList_SET_ITEM(list, pos++, PyString_FromFormat("%d", exif->m_exifinfo->ISOequivalent)); + sprintf(tmp, "%.2f", exif->m_exifinfo->Xresolution); + PyList_SET_ITEM(list, pos++, PyString_FromString(tmp)); + sprintf(tmp, "%.2f", exif->m_exifinfo->Yresolution); + PyList_SET_ITEM(list, pos++, PyString_FromString(tmp)); + PyList_SET_ITEM(list, pos++, PyString_FromString(exif->m_exifinfo->ResolutionUnit)); + sprintf(tmp, "%.2f", exif->m_exifinfo->Brightness); + PyList_SET_ITEM(list, pos++, PyString_FromString(tmp)); + sprintf(tmp, "%.5f sec.", exif->m_exifinfo->ExposureTime); + PyList_SET_ITEM(list, pos++, PyString_FromString(tmp)); + sprintf(tmp, "%.5f", exif->m_exifinfo->ExposureBias); + PyList_SET_ITEM(list, pos++, PyString_FromString(tmp)); + sprintf(tmp, "%.5f", exif->m_exifinfo->Distance); + PyList_SET_ITEM(list, pos++, PyString_FromString(tmp)); + sprintf(tmp, "%.5f", exif->m_exifinfo->CCDWidth); + PyList_SET_ITEM(list, pos++, PyString_FromString(tmp)); + sprintf(tmp, "%.2f", exif->m_exifinfo->ApertureFNumber); + PyList_SET_ITEM(list, pos++, PyString_FromString(tmp)); } else { - imx = (int)((1.0/aspect_ratio)*ox*h/oy); - imy = h; + list = PyList_New(2); + PyList_SET_ITEM(list, 0, PyString_FromString(filename)); + PyList_SET_ITEM(list, 1, PyString_FromString(exif->m_szLastError)); } + exif->ClearExif(); + } + else + { + list = PyList_New(2); + PyList_SET_ITEM(list, 0, PyString_FromString(filename)); + PyList_SET_ITEM(list, 1, PyString_FromString(exif->m_szLastError)); + } + delete exif; - if(resize_mode) pic_buffer = color_resize(pic_buffer, ox, oy, imx, imy); - else pic_buffer = simple_resize(pic_buffer, ox, oy, imx, imy); + return list ? (PyObject*)list : (PyObject*)PyList_New(0); +} - ox = imx; - oy = imy; - } - else cache = true; +int ePicLoad::getData(ePtr &result) +{ + result = 0; + if(m_filepara->pic_buffer == NULL) return 0; - result=new gPixmap(eSize(w, h), 32); + m_filepara->pic_buffer = conv24to32(m_filepara->pic_buffer, m_filepara->ox * m_filepara->oy); + + result=new gPixmap(eSize(m_filepara->max_x, m_filepara->max_y), 32); gSurface *surface = result->surface; int a=0, b=0; int nc=0, oc=0; int o_y=0, u_y=0, v_x=0, h_x=0; - unsigned char clear[4] = {0x00,0x00,0x00,0x00}; - if(background) clear[3]=0xFF; - unsigned char *tmp_buffer=((unsigned char *)(surface->data)); - if(oy < h) + unsigned char *tmp_buffer=((unsigned char *)(surface->data)); + + if(m_filepara->oy < m_filepara->max_y) { - o_y=(h-oy)/2; - u_y=h-oy-o_y; + o_y = (m_filepara->max_y - m_filepara->oy) / 2; + u_y = m_filepara->max_y - m_filepara->oy - o_y; } - if(ox < w) + if(m_filepara->ox < m_filepara->max_x) { - v_x=(w-ox)/2; - h_x=w-ox-v_x; + v_x = (m_filepara->max_x - m_filepara->ox) / 2; + h_x = m_filepara->max_x - m_filepara->ox - v_x; } - //eDebug("o_y=%d u_y=%d v_x=%d h_x=%d", o_y, u_y, v_x, h_x); - - if(oy < h) - for(a=0; a<(o_y*ox); a++, nc+=4) + if(m_filepara->oy < m_filepara->max_y) + { + for(a=0; a<(o_y*m_filepara->ox); a++, nc+=4) { tmp_buffer=((unsigned char *)(surface->data)) + nc; - memcpy(tmp_buffer, clear, sizeof(clear)); + memcpy(tmp_buffer, m_conf.background, sizeof(m_conf.background)); } - - for(a=0; aoy; a++) { - if(ox < w) + if(m_filepara->ox < m_filepara->max_x) + { for(b=0; bdata)) + nc; - memcpy(tmp_buffer, clear, sizeof(clear)); + memcpy(tmp_buffer, m_conf.background, sizeof(m_conf.background)); } + } - for(b=0; b<(ox*4); b+=4, nc+=4) + for(b=0; b<(m_filepara->ox*4); b+=4, nc+=4) { tmp_buffer=((unsigned char *)(surface->data)) + nc; - tmp_buffer[2]=pic_buffer[oc++]; - tmp_buffer[1]=pic_buffer[oc++]; - tmp_buffer[0]=pic_buffer[oc++]; - tmp_buffer[3]=pic_buffer[oc++]; - + tmp_buffer[2] = m_filepara->pic_buffer[oc++]; + tmp_buffer[1] = m_filepara->pic_buffer[oc++]; + tmp_buffer[0] = m_filepara->pic_buffer[oc++]; + tmp_buffer[3] = m_filepara->pic_buffer[oc++]; } - if(ox < w) + if(m_filepara->ox < m_filepara->max_x) + { for(b=0; bdata)) + nc; - memcpy(tmp_buffer, clear, sizeof(clear)); + memcpy(tmp_buffer, m_conf.background, sizeof(m_conf.background)); } + } } - - if(oy < h) - for(a=0; a<(u_y*ox); a++, nc+=4) + + if(m_filepara->oy < m_filepara->max_y) + { + for(a=0; a<(u_y*m_filepara->ox); a++, nc+=4) { tmp_buffer=((unsigned char *)(surface->data)) + nc; - memcpy(tmp_buffer, clear, sizeof(clear)); + memcpy(tmp_buffer, m_conf.background, sizeof(m_conf.background)); } - - //eDebug("[PIC] buffer=%d, nc=%d oc=%d ox=%d, oy=%d",w*h*4, nc, oc, ox, oy); + } surface->clut.data=0; surface->clut.colors=0; surface->clut.start=0; + + delete m_filepara; + m_filepara = NULL; + + return 0; +} + +RESULT ePicLoad::setPara(PyObject *val) +{ + if (!PySequence_Check(val)) + return 0; + if (PySequence_Size(val) < 7) + return 0; + else { + ePyObject fast = PySequence_Fast(val, ""); + m_conf.max_x = PyInt_AsLong( PySequence_Fast_GET_ITEM(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)); - delete [] pic_buffer; + if(bg_str[0] == '#' && strlen(bg_str)==9) + { + int bg = strtoul(bg_str+1, NULL, 16); + m_conf.background[0] = bg&0xFF; //BB + m_conf.background[1] = (bg>>8)&0xFF; //GG + m_conf.background[2] = (bg>>16)&0xFF; //RR + m_conf.background[3] = bg>>24; //AA + } + eDebug("[Picload] setPara max-X=%d max-Y=%d aspect_ratio=%lf cache=%d resize=%d bg=#%02X%02X%02X%02X", m_conf.max_x, m_conf.max_y, m_conf.aspect_ratio, (int)m_conf.usecache, (int)m_conf.resizetype, m_conf.background[3], m_conf.background[2], m_conf.background[1], m_conf.background[0]); + } + return 1; +} + +//------------------------------------------------------------------------------------ - if(cachefile.length() && !cache) +//for old plugins +SWIG_VOID(int) loadPic(ePtr &result, std::string filename, int x, int y, int aspect, int resize_mode, int rotate, int background, std::string cachefile) +{ + long asp1, asp2; + result = 0; + eDebug("deprecated loadPic function used!!! please use the non blocking version! you can see demo code in Pictureplayer plugin... this function is removed in the near future!"); + ePicLoad mPL; + + switch(aspect) { - savePNG( cachefile.c_str(), result); - eDebug("[SAVEPIC] x-size=%d, y-size=%d", ox, oy); + case 1: asp1 = 16*576, asp2 = 9*720; break; //16:9 + case 2: asp1 = 16*576, asp2 = 10*720; break; //16:10 + case 3: asp1 = 5*576, asp2 = 4*720; break; //5:4 + default: asp1 = 4*576, asp2 = 3*720; break; //4:3 } + ePyObject tuple = PyTuple_New(7); + PyTuple_SET_ITEM(tuple, 0, PyLong_FromLong(x)); + PyTuple_SET_ITEM(tuple, 1, PyLong_FromLong(y)); + PyTuple_SET_ITEM(tuple, 2, PyLong_FromLong(asp1)); + PyTuple_SET_ITEM(tuple, 3, PyLong_FromLong(asp2)); + PyTuple_SET_ITEM(tuple, 4, PyLong_FromLong(0)); + PyTuple_SET_ITEM(tuple, 5, PyLong_FromLong(resize_mode)); + if(background) + PyTuple_SET_ITEM(tuple, 6, PyString_FromString("#ff000000")); + else + PyTuple_SET_ITEM(tuple, 6, PyString_FromString("#00000000")); + + mPL.setPara(tuple); + + if(!mPL.startDecode(filename.c_str(), 0, 0, false)) + mPL.getData(result); + return 0; } diff --git a/lib/gdi/picload.h b/lib/gdi/picload.h index 7bb9adf..f64fd2f 100644 --- a/lib/gdi/picload.h +++ b/lib/gdi/picload.h @@ -1,11 +1,107 @@ #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, bool async=true); + void thread_finished(); +public: + void waitFinished(); + PSignal1 PictureData; + + ePicLoad(); + ~ePicLoad(); + + 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); +}; + +//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/gui/esubtitle.cpp b/lib/gui/esubtitle.cpp index c837afc..085a749 100644 --- a/lib/gui/esubtitle.cpp +++ b/lib/gui/esubtitle.cpp @@ -16,6 +16,7 @@ eSubtitleWidget::eSubtitleWidget(eWidget *parent) setBackgroundColor(gRGB(0,0,0,255)); m_page_ok = 0; m_dvb_page_ok = 0; + m_pango_page_ok = 0; CONNECT(m_hide_subtitles_timer->timeout, eSubtitleWidget::clearPage); } diff --git a/lib/python/Components/AVSwitch.py b/lib/python/Components/AVSwitch.py index 8f99b98..00350cb 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: @@ -28,6 +28,27 @@ 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 (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 (4,3) + except IOError: + pass + elif valstr in ("16_9_always", "16_9_letterbox"): # 16:9 + pass + elif valstr in ("16_10_letterbox", "16_10_panscan"): # 16:10 + return (16,10) + return (16,9) + + def getFramebufferScale(self): + aspect = self.getOutputAspect() + fb_size = getDesktop(0).size() + return (aspect[0] * fb_size.height(), aspect[1] * fb_size.width()) + def getAspectRatioSetting(self): valstr = config.av.aspectratio.value if valstr == "4_3_letterbox": diff --git a/lib/python/Plugins/Extensions/DVDBurn/DVDToolbox.py b/lib/python/Plugins/Extensions/DVDBurn/DVDToolbox.py index 836c9fb..ce16259 100644 --- a/lib/python/Plugins/Extensions/DVDBurn/DVDToolbox.py +++ b/lib/python/Plugins/Extensions/DVDBurn/DVDToolbox.py @@ -50,7 +50,7 @@ class DVDToolbox(Screen): "green": self.update, "yellow": self.format, #"blue": self.eject, - "cancel": self.close, + "cancel": self.exit, "pageUp": self.pageUp, "pageDown": self.pageDown }) @@ -63,7 +63,7 @@ class DVDToolbox(Screen): def pageDown(self): self["details"].pageDown() - def update(self, dev="", media_state=""): + def update(self, dev="", action=""): self["space_label"].text = _("Please wait... Loading list...") self["info"].text = "" self["details"].setText("") @@ -89,7 +89,7 @@ class DVDToolbox(Screen): for line in mediuminfo.splitlines(): if line.find("Mounted Media:") > -1: mediatype = line.rsplit(',',1)[1][1:] - if mediatype.find("RW") > 0: + if mediatype.find("RW") > 0 or mediatype.find("RAM") > 0: self.formattable = True else: self.formattable = False @@ -186,7 +186,7 @@ class DVDformatTask(Task): if line.startswith("- media is already formatted"): self.error = self.ERROR_ALREADYFORMATTED self.retryargs = [ "-force" ] - if line.startswith("- media is not blank"): + if line.startswith("- media is not blank") or line.startswith(" -format=full to perform full (lengthy) reformat;"): self.error = self.ERROR_ALREADYFORMATTED self.retryargs = [ "-blank" ] if line.startswith(":-( mounted media doesn't appear to be"): diff --git a/lib/python/Plugins/Extensions/DVDBurn/Process.py b/lib/python/Plugins/Extensions/DVDBurn/Process.py index 89ca90f..750e9d9 100644 --- a/lib/python/Plugins/Extensions/DVDBurn/Process.py +++ b/lib/python/Plugins/Extensions/DVDBurn/Process.py @@ -165,7 +165,7 @@ class DemuxTask(Task): def cleanup(self, failed): if failed: import os - for file in self.generated_files.itervalues(): + for file in self.generated_files: os.remove(file) class MplexTaskPostcondition(Condition): @@ -220,7 +220,7 @@ class RemoveESFiles(Task): def prepare(self): self.args += ["-f"] - self.args += self.demux_task.generated_files.values() + self.args += self.demux_task.generated_files self.args += [self.demux_task.cutfile] class DVDAuthorTask(Task): @@ -368,6 +368,9 @@ class CheckDiskspaceTask(Task): self.global_preconditions.append(DiskspacePrecondition(diskSpaceNeeded)) self.weighting = 5 + def abort(self): + self.finish(aborted = True) + def run(self, callback): failed_preconditions = self.checkPreconditions(True) + self.checkPreconditions(False) if len(failed_preconditions): @@ -791,7 +794,7 @@ class DVDJob(Job): demux = DemuxTask(self, link_name) self.mplextask = MplexTask(self, outputfile=title_filename, demux_task=demux) self.mplextask.end = self.estimateddvdsize - #RemoveESFiles(self, demux) + RemoveESFiles(self, demux) WaitForResidentTasks(self) PreviewTask(self, self.workspace + "/dvd/VIDEO_TS/") output = self.project.settings.output.getValue() diff --git a/lib/python/Plugins/Extensions/DVDBurn/TitleList.py b/lib/python/Plugins/Extensions/DVDBurn/TitleList.py index 345af87..537da0d 100644 --- a/lib/python/Plugins/Extensions/DVDBurn/TitleList.py +++ b/lib/python/Plugins/Extensions/DVDBurn/TitleList.py @@ -74,9 +74,22 @@ class TitleList(Screen, HelpableScreen): self["titles"] = List(list = [ ], enableWrapAround = True, item_height=30, fonts = [gFont("Regular", 20)]) self.updateTitleList() - + + def checkBackgroundJobs(self): + for job in job_manager.getPendingJobs(): + print "type(job):", type(job) + print "Process.DVDJob:", Process.DVDJob + if type(job) == Process.DVDJob: + self.backgroundJob = job + return + self.backgroundJob = None + def showMenu(self): menu = [] + self.checkBackgroundJobs() + if self.backgroundJob: + j = self.backgroundJob + menu.append(("%s: %s (%d%%)" % (j.getStatustext(), j.name, int(100*j.progress/float(j.end))), self.showBackgroundJob)) if self.project.settings.output.getValue() == "dvd": menu.append((_("Burn DVD"), self.burnProject)) elif self.project.settings.output.getValue() == "iso": @@ -97,6 +110,11 @@ class TitleList(Screen, HelpableScreen): if choice: choice[1]() + def showBackgroundJob(self): + job_manager.in_background = False + self.session.openWithCallback(self.JobViewCB, JobView, self.backgroundJob) + self.backgroundJob = None + def titleProperties(self): if self.getCurrentTitle(): self.session.openWithCallback(self.updateTitleList, TitleProperties.TitleProperties, self, self.project, self["titles"].getIndex()) @@ -217,7 +235,7 @@ class TitleList(Screen, HelpableScreen): totalsize += title.estimatedDiskspace self["titles"].list = res self.updateSize(totalsize) - + def updateSize(self, totalsize): size = int((totalsize/1024)/1024) max_SL = 4370 diff --git a/lib/python/Plugins/Extensions/DVDPlayer/plugin.py b/lib/python/Plugins/Extensions/DVDPlayer/plugin.py index cb5f0e0..593d4d2 100644 --- a/lib/python/Plugins/Extensions/DVDPlayer/plugin.py +++ b/lib/python/Plugins/Extensions/DVDPlayer/plugin.py @@ -491,7 +491,7 @@ class DVDPlayer(Screen, InfoBarBase, InfoBarNotifications, InfoBarSeek, InfoBarP def askLeavePlayer(self): choices = [(_("Continue playing"), "play"), (_("Exit"), "exit")] if not self.physicalDVD: - choices.insert(1,(_("Return to file browser"), "browser")) + choices.insert(1,(_("Return to file browser"), "browser")) self.session.openWithCallback(self.exitCB, ChoiceBox, title=_("Leave DVD Player?"), list = choices) def sendKey(self, key): @@ -590,19 +590,16 @@ class DVDPlayer(Screen, InfoBarBase, InfoBarNotifications, InfoBarSeek, InfoBarP print "cur_dlg", self.session.current_dialog def exitCB(self, answer): - if answer is not None: - if answer[1] == "exit": - if self.service: - self.service = None - self.close() - if answer[1] == "browser": + if not answer or answer and answer[1] == "exit": + if self.service: + self.service = None + self.close() + if answer and answer[1] == "browser": #TODO check here if a paused dvd playback is already running... then re-start it... #else - if self.service: - self.service = None - self.showFileBrowser() - else: - pass + if self.service: + self.service = None + self.showFileBrowser() def __onClose(self): for i in (("/proc/stb/video/aspect", self.old_aspect), ("/proc/stb/video/policy", self.old_policy), ("/proc/stb/denc/0/wss", self.old_wss)): diff --git a/lib/python/Plugins/Extensions/MediaPlayer/plugin.py b/lib/python/Plugins/Extensions/MediaPlayer/plugin.py index 0d5305d..babef3e 100644 --- a/lib/python/Plugins/Extensions/MediaPlayer/plugin.py +++ b/lib/python/Plugins/Extensions/MediaPlayer/plugin.py @@ -863,17 +863,22 @@ class MediaPlayer(Screen, InfoBarBase, InfoBarSeek, InfoBarAudioSelection, InfoB self.session.open(Subtitles) def hotplugCB(self, dev, media_state): - if dev == harddiskmanager.getCD(): - from Components.Scanner import scanDevice - devpath = harddiskmanager.getAutofsMountpoint(harddiskmanager.getCD()) - self.cdAudioTrackFiles = [] - res = scanDevice(devpath) - list = [ (r.description, r, res[r], self.session) for r in res ] - if list: - (desc, scanner, files, session) = list[0] - for file in files: - if file.mimetype == "audio/x-cda": - self.cdAudioTrackFiles.append(file.path) + if dev == harddiskmanager.getCD(): + if media_state == "1": + from Components.Scanner import scanDevice + devpath = harddiskmanager.getAutofsMountpoint(harddiskmanager.getCD()) + self.cdAudioTrackFiles = [] + res = scanDevice(devpath) + list = [ (r.description, r, res[r], self.session) for r in res ] + if list: + (desc, scanner, files, session) = list[0] + for file in files: + if file.mimetype == "audio/x-cda": + self.cdAudioTrackFiles.append(file.path) + else: + self.cdAudioTrackFiles = [] + if self.isAudioCD: + self.clear_playlist() class MediaPlayerLCDScreen(Screen): skin = """ diff --git a/lib/python/Plugins/Extensions/PicturePlayer/plugin.py b/lib/python/Plugins/Extensions/PicturePlayer/plugin.py index ea906f0..aeca12d 100644 --- a/lib/python/Plugins/Extensions/PicturePlayer/plugin.py +++ b/lib/python/Plugins/Extensions/PicturePlayer/plugin.py @@ -1,384 +1,150 @@ -from enigma import eTimer, loadPic, getExif +from enigma import ePicLoad, eTimer, getDesktop + from Screens.Screen import Screen -from Screens.ServiceInfo import ServiceInfoList, ServiceInfoListEntry -from Components.ActionMap import ActionMap, NumberActionMap +from Tools.Directories import resolveFilename, pathExists, SCOPE_MEDIA +from Plugins.Plugin import PluginDescriptor + from Components.Pixmap import Pixmap, MovingPixmap +from Components.ActionMap import ActionMap, NumberActionMap from Components.Label import Label - -from Components.ConfigList import ConfigList -from Components.config import * - -from Tools.Directories import resolveFilename, fileExists, pathExists, createDir, SCOPE_MEDIA +from Components.Button import Button from Components.FileList import FileList from Components.AVSwitch import AVSwitch +from Components.Sources.List import List +from Components.ConfigList import ConfigList -from Plugins.Plugin import PluginDescriptor +from Components.config import config, ConfigSubsection, ConfigInteger, ConfigSelection, ConfigText, ConfigEnableDisable, KEY_LEFT, KEY_RIGHT, KEY_0, getConfigListEntry + +def getScale(): + return AVSwitch().getFramebufferScale() config.pic = ConfigSubsection() -config.pic.slidetime = ConfigInteger(default=10, limits=(5, 60)) -config.pic.resize = ConfigSelection(default="0", choices = [("0", _("simple")), ("1", _("better"))]) +config.pic.framesize = ConfigInteger(default=30, limits=(5, 99)) +config.pic.slidetime = ConfigInteger(default=10, limits=(10, 60)) +config.pic.resize = ConfigSelection(default="1", choices = [("0", _("simple")), ("1", _("better"))]) config.pic.cache = ConfigEnableDisable(default=True) config.pic.lastDir = ConfigText(default=resolveFilename(SCOPE_MEDIA)) -config.pic.rotate = ConfigSelection(default="0", choices = [("0", _("none")), ("1", _("manual")), ("2", _("by Exif"))]) - -def getAspect(): - val = AVSwitch().getAspectRatioSetting() - return val/2 +config.pic.infoline = ConfigEnableDisable(default=True) +config.pic.loop = ConfigEnableDisable(default=True) +config.pic.bgcolor = ConfigSelection(default="#00000000", choices = [("#00000000", _("black")),("#009eb9ff", _("blue")),("#00ff5a51", _("red")), ("#00ffe875", _("yellow")), ("#0038FF48", _("green"))]) +config.pic.textcolor = ConfigSelection(default="#0038FF48", choices = [("#00000000", _("black")),("#009eb9ff", _("blue")),("#00ff5a51", _("red")), ("#00ffe875", _("yellow")), ("#0038FF48", _("green"))]) -#------------------------------------------------------------------------------------------ +class picshow(Screen): + def __init__(self, session): + self.skin = """ + + + + + + + + + + + + """ -class ThumbView(Screen): - skin = """ - - - - - - - - - - - - - - - - """ - - def __init__(self, session, filelist, name, path): - self.skin = ThumbView.skin Screen.__init__(self, session) - self["actions"] = ActionMap(["OkCancelActions", "DirectionActions", "MovieSelectionActions"], + self["actions"] = ActionMap(["OkCancelActions", "ColorActions", "DirectionActions"], { - "cancel": self.Exit, - "ok": self.KeyOk, - "showEventInfo": self.StartExif, - "right": self.key_right, - "left": self.key_left, - "up": self.key_up, - "down": self.key_down + "cancel": self.KeyExit, + "red": self.KeyRed, + "yellow": self.KeyYellow, + "blue": self.KeyBlue, + "ok": self.KeyOk }, -1) - - for x in range(6): - self["label"+str(x)] = Label() - self["thumb"+str(x)] = Pixmap() - self["frame"] = MovingPixmap() - - self.aspect = getAspect() - self.path = path - self.filelist = filelist - self.currPage = -1 - self.index = 0 - self.old_index = 0 - self.thumblist = [] - self.thumbindex = 0 - self.list = [] - self.poslist = [[50,63],[265,63],[480,63],[50,288],[265,288],[480,288]] - - count=0 - pos=0 - for x in self.filelist: - if x[0][1] == False: - self.list.append((x[0][0], self.path + x[0][0], count/6, pos, "(" + str(count+1) + ") ")) - pos += 1 - if pos == 6: - pos = 0 - if x[0][0] == name: - self.index = count - count += 1 - self.maxentry = len(self.list)-1 - - if self.maxentry < 0: - self["label0"].setText(_("no Picture found")) + + self["key_red"] = Button(_("Thumbnails")) + self["key_green"] = Button() + self["key_yellow"] = Button(_("Exif")) + self["key_blue"] = Button(_("Setup")) + self["label"] = Label() + self["thn"] = Pixmap() + + currDir = config.pic.lastDir.value + if not pathExists(currDir): + currDir = "/" + + self.filelist = FileList(currDir, matchingPattern = "(?i)^.*\.(jpeg|jpg|jpe|png|bmp|gif)") + self["filelist"] = self.filelist + self["filelist"].onSelectionChanged.append(self.selectionChanged) self.ThumbTimer = eTimer() self.ThumbTimer.callback.append(self.showThumb) - self.fillPage() - - def key_left(self): - self.index -= 1 - if self.index < 0: - self.index = self.maxentry - self.fillPage() - - def key_right(self): - self.index += 1 - if self.index > self.maxentry: - self.index = 0 - self.fillPage() - - def key_up(self): - self.index -= 3 - if self.index < 0: - self.index = 0 - self.fillPage() - - def key_down(self): - self.index += 3 - if self.index > self.maxentry: - self.index = self.maxentry - self.fillPage() + self.picload = ePicLoad() + self.picload.PictureData.get().append(self.showPic) - def fillPage(self): - if self.maxentry < 0: - return + self.onLayoutFinish.append(self.setConf) - self["frame"].moveTo(self.poslist[self.list[self.index][3]][0], self.poslist[self.list[self.index][3]][1], 1) - self["frame"].startMoving() - - if self.list[self.index][2] != self.currPage: - self.currPage = self.list[self.index][2] - textlist = ["","","","","",""] - self.thumblist = ["","","","","",""] - - for x in self.list: - if x[2] == self.currPage: - textlist[x[3]] = x[4] + x[0] - self.thumblist[x[3]] = x[0] - - for x in range(6): - self["label"+str(x)].setText(textlist[x]) - self["thumb"+str(x)].hide() - - self.ThumbTimer.start(500, True) + def showPic(self, picInfo=""): + ptr = self.picload.getData() + if ptr != None: + self["thn"].instance.setPixmap(ptr.__deref__()) + self["thn"].show() + + text = picInfo.split('\n',1) + self["label"].setText(text[1]) + self["label"].show() def showThumb(self): - if self.thumblist[self.thumbindex] != "": - cachefile = "" - if config.pic.cache.value: - cachedir = self.path + ".Thumbnails/" - cachefile = cachedir + self.thumblist[self.thumbindex] + str(180) + str(160) + str(self.aspect) - if not pathExists(cachedir): - if not createDir(cachedir): - cachefile = "" - - ptr = loadPic(self.path + self.thumblist[self.thumbindex], 180, 160, self.aspect, int(config.pic.resize.value), int(config.pic.rotate.value), 1, cachefile, 1) - if ptr != None: - self["thumb"+str(self.thumbindex)].show() - self["thumb"+str(self.thumbindex)].instance.setPixmap(ptr) - - self.thumbindex += 1 - if self.thumbindex < 6: + if not self.filelist.canDescent(): + if self.picload.getThumbnail(self.filelist.getCurrentDirectory() + self.filelist.getFilename()) == 1: self.ThumbTimer.start(500, True) - else: - self.thumbindex = 0 - else: - self.thumbindex = 0 - - def StartExif(self): - if self.maxentry < 0: - return - - self.session.open(ExifView, self.list[self.index][1], self.list[self.index][0]) - def KeyOk(self): - if self.maxentry < 0: - return - - self.old_index = self.index - self.session.openWithCallback(self.returnView ,PicView, self.filelist, self.list[self.index][0], self.path) - - def returnView(self, val=0): - self.index = val - if self.old_index != self.index: - self.fillPage() + def selectionChanged(self): + if not self.filelist.canDescent(): + self.ThumbTimer.start(500, True) + else: + self["label"].hide() + self["thn"].hide() - def Exit(self): - self.close(self.index) - -#------------------------------------------------------------------------------------------ - -class PicView(Screen): - skin = """ - - - - - - - - - - - """ + def KeyRed(self): + #if not self.filelist.canDescent(): + self.session.openWithCallback(self.callbackView, Pic_Thumb, self.filelist.getFileList(), self.filelist.getSelectionIndex(), self.filelist.getCurrentDirectory()) - def __init__(self, session, filelist, name, path): - self.skin = PicView.skin - Screen.__init__(self, session) - - self["actions"] = ActionMap(["OkCancelActions", "ColorActions", "MovieSelectionActions"], - { - "cancel": self.Exit, - "showEventInfo": self.StartExif, - "green": self.Play, - "yellow": self.Pause, - "blue": self.nextPic, - "red": self.prevPic - }, -1) - - self.aspect = getAspect() - self.blinking = False - self.autoShow = True - self.slideOn = False - self.pauseOn = False - self.index = 0 - self.old = 0 - self.list = [] - - count=0 - for x in filelist: - if x[0][1] == False: - self.list.append((x[0][0], path + x[0][0], 0)) - if x[0][0] == name: - self.index = count - count += 1 - self.maxentry = len(self.list)-1 - - self["file"] = Label(_("please wait, loading picture...")) - self["picture"] = Pixmap() - self["point"] = Pixmap() - self["play"] = Pixmap() - self["pause"] = Pixmap() - - self.decodeTimer = eTimer() - self.decodeTimer.callback.append(self.decodePic) - self.decodeTimer.start(300, True) - - self.slideTimer = eTimer() - self.slideTimer.callback.append(self.slidePic) - - - def Pause(self): - if self.slideOn: - if self.pauseOn: - self.pauseOn=False - self["pause"].show() - else: - self.pauseOn=True - self["play"].show() - self.slideValue = 0 - - def Play(self): - if self.pauseOn == False: - if self.slideOn: - self.slideOn=False - self["play"].show() - else: - self.slideOn=True - self.slideTimer.start(1000, True) - - self.slideValue = int(config.pic.slidetime.value) - - def slidePic(self): - if self.slideOn == True and self.pauseOn == False: - self.blinkingWidget("play") - self.slideValue -= 1 - if self.slideValue <= 0: - self.slideValue = int(config.pic.slidetime.value) - self.nextPic() - - self.slideTimer.start(1000, True) - - if self.pauseOn: - self.blinkingWidget("pause") - self.slideTimer.start(1000, True) - - def decodePic(self): - self.currPic = loadPic(self.list[self.index][1], 560, 450, self.aspect, int(config.pic.resize.value), int(config.pic.rotate.value),1) - self["point"].hide() - if self.autoShow: - self.showPic() - self.autoShow = False - - def showPic(self): - if self.currPic != None: - self.old = self.index - self["file"].setText(self.list[self.old][0] + " (" + str(self.old+1) + "/" + str(self.maxentry+1) + ")") - self["picture"].instance.setPixmap(self.currPic) - - self.next() - self["point"].show() - self.decodeTimer.start(300, True) - - def nextPic(self): - self.showPic() - - def prevPic(self): - self.index = self.old - self.prev() - self.autoShow = True - self["point"].show() - self.decodeTimer.start(300, True) - - def next(self): - self.index += 1 - if self.index > self.maxentry: - self.index = 0 + def KeyYellow(self): + if not self.filelist.canDescent(): + self.session.open(Pic_Exif, self.picload.getInfo(self.filelist.getCurrentDirectory() + self.filelist.getFilename())) + + def KeyBlue(self): + self.session.openWithCallback(self.setConf ,Pic_Setup) - def prev(self): - self.index -= 1 - if self.index < 0: - self.index = self.maxentry - - def blinkingWidget(self, name): - if self.blinking: - self.blinking=False - self[name].show() + def KeyOk(self): + if self.filelist.canDescent(): + self.filelist.descent() else: - self.blinking=True - self[name].hide() + self.session.openWithCallback(self.callbackView, Pic_Full_View, self.filelist.getFileList(), self.filelist.getSelectionIndex(), self.filelist.getCurrentDirectory()) - def StartExif(self): - if self.pauseOn == False: - self.Pause() - self.session.openWithCallback(self.StopExif ,ExifView, self.list[self.old][1], self.list[self.old][0]) + 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(), sc[0], sc[1], config.pic.cache.value, int(config.pic.resize.value), "#00000000")) - def StopExif(self): - if self.pauseOn: - self.Pause() - - def Exit(self): - self.close(self.old) + def callbackView(self, val=0): + if val > 0: + self.filelist.moveToIndex(val) -#------------------------------------------------------------------------------------------ + def KeyExit(self): + del self.picload -class ExifView(Screen): - skin = """ - - - """ - - def __init__(self, session, fullname, name): - self.skin = ExifView.skin - Screen.__init__(self, session) + if self.filelist.getCurrentDirectory() is None: + config.pic.lastDir.value = "/" + else: + config.pic.lastDir.value = self.filelist.getCurrentDirectory() - self["actions"] = ActionMap(["OkCancelActions"], - { - "cancel": self.close - }, -1) - - dlist = ["Name:", "EXIF-Version:", "Camera-Make:", "Camera-Model:", "Date/Time:", "User Comments:", "Width / Height:", "Orientation:", "Metering Mode:", "Exposure Program:", "Light Source:", "Flash used:", "CompressedBitsPerPixel:", "ISO Speed Rating:", "X-Resolution:", "Y-Resolution:", "Resolution Unit:", "Brightness:", "Exposure Time:", "Exposure Bias:", "Distance:", "CCD-Width:", "ApertureFNumber:"] - tlist = [ ] - self["exiflist"] = ServiceInfoList(tlist) - tlist.append(ServiceInfoListEntry(dlist[0], name)) - count=1 - for x in getExif(fullname): - tlist.append(ServiceInfoListEntry(dlist[count], x)) - count += 1 + config.pic.save() + self.close() #------------------------------------------------------------------------------------------ -class PicSetup(Screen): - skin = """ - - - """ - +class Pic_Setup(Screen): def __init__(self, session): - self.skin = PicSetup.skin + self.skin = """ + + """ Screen.__init__(self, session) self["actions"] = NumberActionMap(["SetupActions"], @@ -398,12 +164,16 @@ class PicSetup(Screen): "9": self.keyNumber }, -1) - self.list = [] - self["liste"] = ConfigList(self.list) - self.list.append(getConfigListEntry(_("Slideshow Interval (sec.)"), config.pic.slidetime)) - self.list.append(getConfigListEntry(_("Scaling Mode"), config.pic.resize)) - self.list.append(getConfigListEntry(_("Cache Thumbnails"), config.pic.cache)) - #self.list.append(getConfigListEntry(_("Rotate Picture"), config.pic.rotate)) + list = [] + self["liste"] = ConfigList(list) + list.append(getConfigListEntry(_("Slideshow Interval (sec.)"), config.pic.slidetime)) + list.append(getConfigListEntry(_("Scaling Mode"), config.pic.resize)) + list.append(getConfigListEntry(_("Cache Thumbnails"), config.pic.cache)) + list.append(getConfigListEntry(_("show Infoline"), config.pic.infoline)) + list.append(getConfigListEntry(_("Frame size in full view"), config.pic.framesize)) + list.append(getConfigListEntry(_("slide picture in loop"), config.pic.loop)) + list.append(getConfigListEntry(_("backgroundcolor"), config.pic.bgcolor)) + list.append(getConfigListEntry(_("textcolor"), config.pic.textcolor)) def keyLeft(self): self["liste"].handleKey(KEY_LEFT) @@ -414,126 +184,385 @@ class PicSetup(Screen): def keyNumber(self, number): self["liste"].handleKey(KEY_0 + number) +#--------------------------------------------------------------------------- + +class Pic_Exif(Screen): + def __init__(self, session, exiflist): + self.skin = """ + + + {"template": [ MultiContentEntryText(pos = (5, 5), size = (250, 30), flags = RT_HALIGN_LEFT, text = 0), MultiContentEntryText(pos = (260, 5), size = (290, 30), flags = RT_HALIGN_LEFT, text = 1)], "fonts": [gFont("Regular", 20)], "itemHeight": 30 } + + + """ + Screen.__init__(self, session) -#------------------------------------------------------------------------------------------ + self["actions"] = ActionMap(["OkCancelActions"], + { + "cancel": self.close + }, -1) + + exifdesc = [_("filename")+':', "EXIF-Version:", "Make:", "Camera:", "Date/Time:", "Width / Height:", "Flash used:", "Orientation:", "User Comments:", "Metering Mode:", "Exposure Program:", "Light Source:", "CompressedBitsPerPixel:", "ISO Speed Rating:", "X-Resolution:", "Y-Resolution:", "Resolution Unit:", "Brightness:", "Exposure Time:", "Exposure Bias:", "Distance:", "CCD-Width:", "ApertureFNumber:"] + list = [] -class picmain(Screen): - skin = """ - - - - - - - - - - """ - - def __init__(self, session): - self.skin = picmain.skin + for x in range(len(exiflist)): + if x>0: + list.append((exifdesc[x], exiflist[x])) + else: + name = exiflist[x].split('/')[-1] + list.append((exifdesc[x], name)) + self["menu"] = List(list) + +#---------------------------------------------------------------------------------------- + +T_INDEX = 0 +T_FRAME_POS = 1 +T_PAGE = 2 +T_NAME = 3 +T_FULL = 4 + +class Pic_Thumb(Screen): + def __init__(self, session, piclist, lastindex, path): + + self.textcolor = config.pic.textcolor.value + self.color = config.pic.bgcolor.value + textsize = 20 + self.spaceX = 35 + self.picX = 190 + self.spaceY = 30 + self.picY = 200 + + size_w = getDesktop(0).size().width() + size_h = getDesktop(0).size().height() + self.thumbsX = size_w / (self.spaceX + self.picX) # thumbnails in X + self.thumbsY = size_h / (self.spaceY + self.picY) # thumbnails in Y + self.thumbsC = self.thumbsX * self.thumbsY # all thumbnails + + self.positionlist = [] + skincontent = "" + + posX = -1 + for x in range(self.thumbsC): + posY = x / self.thumbsX + posX += 1 + if posX >= self.thumbsX: + posX = 0 + + absX = self.spaceX + (posX*(self.spaceX + self.picX)) + absY = self.spaceY + (posY*(self.spaceY + self.picY)) + self.positionlist.append((absX, absY)) + skincontent += "" + + skincontent += "" + + + # Screen, backgroundlabel and MovingPixmap + self.skin = " \ + " + skincontent + "" + Screen.__init__(self, session) - - self["actions"] = ActionMap(["OkCancelActions", "DirectionActions", "ColorActions", "MovieSelectionActions"], + + self["actions"] = ActionMap(["OkCancelActions", "ColorActions", "DirectionActions", "MovieSelectionActions"], { - "ok": self.KeyOk, "cancel": self.Exit, - "right": self.rightDown, - "left": self.leftUp, - "up": self.up, - "down": self.down, + "ok": self.KeyOk, + "left": self.key_left, + "right": self.key_right, + "up": self.key_up, + "down": self.key_down, "showEventInfo": self.StartExif, - "contextMenu": self.Settings, - "red": self.StartThumb }, -1) - self.aspect = getAspect() - currDir = config.pic.lastDir.value - if not pathExists(currDir): - currDir = "/" + self["frame"] = MovingPixmap() + for x in range(self.thumbsC): + self["label"+str(x)] = Label() + self["thumb"+str(x)] = Pixmap() + + self.Thumbnaillist = [] + self.filelist = [] + self.currPage = -1 + self.dirlistcount = 0 + self.path = path - self.filelist = FileList(currDir, matchingPattern = "(?i)^.*\.(jpeg|jpg|jpe|png|bmp|gif)") - self["filelist"] = self.filelist - self["thumbnail"] = Pixmap() + index = 0 + framePos = 0 + Page = 0 + for x in piclist: + if x[0][1] == False: + self.filelist.append((index, framePos, Page, x[0][0], path + x[0][0])) + index += 1 + framePos += 1 + if framePos > (self.thumbsC -1): + framePos = 0 + Page += 1 + else: + self.dirlistcount += 1 + + self.maxentry = len(self.filelist)-1 + self.index = lastindex - self.dirlistcount + if self.index < 0: + self.index = 0 + + self.picload = ePicLoad() + self.picload.PictureData.get().append(self.showPic) + + self.onLayoutFinish.append(self.setPicloadConf) self.ThumbTimer = eTimer() - self.ThumbTimer.callback.append(self.showThumb) - self.ThumbTimer.start(500, True) + self.ThumbTimer.callback.append(self.showPic) + + def setPicloadConf(self): + 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: + return + + pos = self.positionlist[self.filelist[self.index][T_FRAME_POS]] + self["frame"].moveTo( pos[0], pos[1], 1) + self["frame"].startMoving() - def up(self): - self["filelist"].up() - self.ThumbTimer.start(1500, True) + if self.currPage != self.filelist[self.index][T_PAGE]: + self.currPage = self.filelist[self.index][T_PAGE] + self.newPage() + + def newPage(self): + self.Thumbnaillist = [] + #clear Labels and Thumbnail + for x in range(self.thumbsC): + self["label"+str(x)].setText("") + self["thumb"+str(x)].hide() + #paint Labels and fill Thumbnail-List + for x in self.filelist: + if x[T_PAGE] == self.currPage: + self["label"+str(x[T_FRAME_POS])].setText("(" + str(x[T_INDEX]+1) + ") " + x[T_NAME]) + self.Thumbnaillist.append([0, x[T_FRAME_POS], x[T_FULL]]) + + #paint Thumbnail start + self.showPic() - def down(self): - self["filelist"].down() - self.ThumbTimer.start(1500, True) + def showPic(self, picInfo=""): + for x in range(len(self.Thumbnaillist)): + if self.Thumbnaillist[x][0] == 0: + if self.picload.getThumbnail(self.Thumbnaillist[x][2]) == 1: #zu tun probier noch mal + self.ThumbTimer.start(500, True) + else: + self.Thumbnaillist[x][0] = 1 + break + elif self.Thumbnaillist[x][0] == 1: + self.Thumbnaillist[x][0] = 2 + ptr = self.picload.getData() + if ptr != None: + self["thumb" + str(self.Thumbnaillist[x][1])].instance.setPixmap(ptr.__deref__()) + self["thumb" + str(self.Thumbnaillist[x][1])].show() + + def key_left(self): + self.index -= 1 + if self.index < 0: + self.index = self.maxentry + self.paintFrame() - def leftUp(self): - self["filelist"].pageUp() - self.ThumbTimer.start(1500, True) + def key_right(self): + self.index += 1 + if self.index > self.maxentry: + self.index = 0 + self.paintFrame() - def rightDown(self): - self["filelist"].pageDown() - self.ThumbTimer.start(1500, True) + def key_up(self): + self.index -= self.thumbsX + if self.index < 0: + self.index =self.maxentry + self.paintFrame() + + def key_down(self): + self.index += self.thumbsX + if self.index > self.maxentry: + self.index = 0 + self.paintFrame() - def showThumb(self): - if not self.filelist.canDescent(): - cachefile = "" - if config.pic.cache.value: - cachedir = self.filelist.getCurrentDirectory() + ".Thumbnails/" - cachefile = cachedir + self.filelist.getFilename() + str(180) + str(160) + str(self.aspect) - if not pathExists(cachedir): - if not createDir(cachedir): - cachefile = "" - - ptr = loadPic(self.filelist.getCurrentDirectory() + self.filelist.getFilename(), 180, 160, self.aspect, int(config.pic.resize.value), 0, 0, cachefile, 1) - if ptr != None: - self["thumbnail"].show() - self["thumbnail"].instance.setPixmap(ptr) - else: - self["thumbnail"].hide() + def StartExif(self): + if self.maxentry < 0: + return + self.session.open(Pic_Exif, self.picload.getInfo(self.filelist[self.index][T_FULL])) def KeyOk(self): - if self.filelist.canDescent(): - self.filelist.descent() - else: - self.session.openWithCallback(self.returnVal, PicView, self.filelist.getFileList(), self.filelist.getFilename(), self.filelist.getCurrentDirectory()) - - def StartThumb(self): - self.session.openWithCallback(self.returnVal, ThumbView, self.filelist.getFileList(), self.filelist.getFilename(), self.filelist.getCurrentDirectory()) + if self.maxentry < 0: + return + self.old_index = self.index + self.session.openWithCallback(self.callbackView, Pic_Full_View, self.filelist, self.index, self.path) - def returnVal(self, val=0): - if val > 0: - for x in self.filelist.getFileList(): - if x[0][1] == True: - val += 1 - self.filelist.moveToIndex(val) + def callbackView(self, val=0): + self.index = val + if self.old_index != self.index: + self.paintFrame() + def Exit(self): + del self.picload + self.close(self.index + self.dirlistcount) - def StartExif(self): - if not self.filelist.canDescent(): - self.session.open(ExifView, self.filelist.getCurrentDirectory() + self.filelist.getFilename(), self.filelist.getFilename()) +#--------------------------------------------------------------------------- + +class Pic_Full_View(Screen): + def __init__(self, session, filelist, index, path): + + self.textcolor = config.pic.textcolor.value + self.bgcolor = config.pic.bgcolor.value + space = config.pic.framesize.value + size_w = getDesktop(0).size().width() + size_h = getDesktop(0).size().height() + + self.skin = " \ + \ + \ + \ + " + + Screen.__init__(self, session) + + self["actions"] = ActionMap(["OkCancelActions", "ColorActions", "DirectionActions", "MovieSelectionActions"], + { + "cancel": self.Exit, + "green": self.PlayPause, + "yellow": self.PlayPause, + "blue": self.nextPic, + "red": self.prevPic, + "left": self.prevPic, + "right": self.nextPic, + "showEventInfo": self.StartExif, + }, -1) + + self["point"] = Pixmap() + self["pic"] = Pixmap() + self["play_icon"] = Pixmap() + self["file"] = Label(_("please wait, loading picture...")) + + self.old_index = 0 + self.filelist = [] + self.lastindex = index + self.currPic = [] + self.shownow = True + self.dirlistcount = 0 + + for x in filelist: + if len(filelist[0]) == 3: #orig. filelist + if x[0][1] == False: + self.filelist.append(path + x[0][0]) + else: + self.dirlistcount += 1 + else: # thumbnaillist + self.filelist.append(x[T_FULL]) + + self.maxentry = len(self.filelist)-1 + self.index = index - self.dirlistcount + if self.index < 0: + self.index = 0 + + self.picload = ePicLoad() + self.picload.PictureData.get().append(self.finish_decode) + + self.slideTimer = eTimer() + self.slideTimer.callback.append(self.slidePic) - def Settings(self): - self.session.open(PicSetup) + if self.maxentry >= 0: + self.onLayoutFinish.append(self.setPicloadConf) + + def setPicloadConf(self): + 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: + self["file"].hide() + self.start_decode() + + def ShowPicture(self): + if self.shownow and len(self.currPic): + self.shownow = False + self["file"].setText(self.currPic[0]) + self.lastindex = self.currPic[1] + self["pic"].instance.setPixmap(self.currPic[2].__deref__()) + self.currPic = [] + + self.next() + self.start_decode() - def Exit(self): - if self.filelist.getCurrentDirectory() is None: - config.pic.lastDir.value = "/" + def finish_decode(self, picInfo=""): + self["point"].hide() + ptr = self.picload.getData() + if ptr != None: + text = "" + try: + text = picInfo.split('\n',1) + text = "(" + str(self.index+1) + "/" + str(self.maxentry+1) + ") " + text[0].split('/')[-1] + except: + pass + self.currPic = [] + self.currPic.append(text) + self.currPic.append(self.index) + self.currPic.append(ptr) + self.ShowPicture() + + def start_decode(self): + self.picload.startDecode(self.filelist[self.index]) + self["point"].show() + + def next(self): + self.index += 1 + if self.index > self.maxentry: + self.index = 0 + + def prev(self): + self.index -= 1 + if self.index < 0: + self.index = self.maxentry + + def slidePic(self): + print "slide to next Picture index=" + str(self.lastindex) + if config.pic.loop.value==False and self.lastindex == self.maxentry: + self.PlayPause() + self.shownow = True + self.ShowPicture() + + def PlayPause(self): + if self.slideTimer.isActive(): + self.slideTimer.stop() + self["play_icon"].hide() else: - config.pic.lastDir.value = self.filelist.getCurrentDirectory() + self.slideTimer.start(config.pic.slidetime.value*1000) + self["play_icon"].show() + self.nextPic() - config.pic.save() - self.close() + def prevPic(self): + self.currPic = [] + self.index = self.lastindex + self.prev() + self.start_decode() + self.shownow = True + + def nextPic(self): + self.shownow = True + self.ShowPicture() + + def StartExif(self): + if self.maxentry < 0: + return + self.session.open(Pic_Exif, self.picload.getInfo(self.filelist[self.lastindex])) + + def Exit(self): + del self.picload + self.close(self.lastindex + self.dirlistcount) #------------------------------------------------------------------------------------------ def main(session, **kwargs): - session.open(picmain) + session.open(picshow) def filescan_open(list, session, **kwargs): # Recreate List as expected by PicView filelist = [((file.path, False), None) for file in list] - session.open(PicView, filelist, "", "") + session.open(Pic_Full_View, filelist, 0, file.path) def filescan(**kwargs): from Components.Scanner import Scanner, ScanPath @@ -557,5 +586,5 @@ def filescan(**kwargs): def Plugins(**kwargs): return \ - [PluginDescriptor(name="PicturePlayer", description="Picture Viewer (BMP, PNG, JPG, GIF)", icon="pictureplayer.png", where = PluginDescriptor.WHERE_PLUGINMENU, fnc=main), - PluginDescriptor(name="PicturePlayer", where = PluginDescriptor.WHERE_FILESCAN, fnc = filescan)] + [PluginDescriptor(name=_("PicturePlayer"), description=_("fileformats (BMP, PNG, JPG, GIF)"), icon="pictureplayer.png", where = PluginDescriptor.WHERE_PLUGINMENU, fnc=main), + PluginDescriptor(name=_("PicturePlayer"), where = PluginDescriptor.WHERE_FILESCAN, fnc = filescan)] diff --git a/lib/python/Plugins/SystemPlugins/Hotplug/plugin.py b/lib/python/Plugins/SystemPlugins/Hotplug/plugin.py index 97ddf4a..e593e94 100644 --- a/lib/python/Plugins/SystemPlugins/Hotplug/plugin.py +++ b/lib/python/Plugins/SystemPlugins/Hotplug/plugin.py @@ -53,7 +53,7 @@ class Hotplug(Protocol): for callback in hotplugNotifier: try: - callback(dev, media_state) + callback(dev, action or media_state) except AttributeError: hotplugNotifier.remove(callback) diff --git a/lib/python/Plugins/SystemPlugins/NFIFlash/downloader.py b/lib/python/Plugins/SystemPlugins/NFIFlash/downloader.py index c2046af..160620f 100644 --- a/lib/python/Plugins/SystemPlugins/NFIFlash/downloader.py +++ b/lib/python/Plugins/SystemPlugins/NFIFlash/downloader.py @@ -18,6 +18,7 @@ import urllib from twisted.web import client from twisted.internet import reactor, defer from twisted.python import failure +from Plugins.SystemPlugins.Hotplug.plugin import hotplugNotifier class UserRequestedCancel(Exception): pass @@ -119,10 +120,10 @@ class NFIDownload(Screen): - - - - + + + + @@ -169,6 +170,7 @@ class NFIDownload(Screen): self.box = HardwareInfo().get_device_name() self.feed_base = "http://www.dreamboxupdate.com/opendreambox/1.5/%s/images/" % self.box self.nfi_filter = "" # "release" # only show NFIs containing this string, or all if "" + self.wizard_mode = False self["actions"] = ActionMap(["OkCancelActions", "ColorActions", "DirectionActions", "EPGSelectActions"], { @@ -205,7 +207,7 @@ class NFIDownload(Screen): self["key_yellow"].text = (_("Change dir.")) else: self["key_yellow"].text = (_("Select image")) - self["key_blue"].text = (_("Fix USB stick")) + self["key_blue"].text = (_("USB stick wizard")) def switchList(self,to_where=None): if self.download or not self["feedlist"].isValid(): @@ -335,7 +337,7 @@ class NFIDownload(Screen): self.download = self.nfo_download self.downloading(True) client.getPage(nfourl).addCallback(self.nfo_finished).addErrback(self.nfo_failed) - self["statusbar"].text = _("Downloading image description...") + self["statusbar"].text = ("Downloading image description...") def nfo_failed(self, failure_instance): print "[nfo_failed] " + str(failure_instance) @@ -399,8 +401,8 @@ class NFIDownload(Screen): print "couldn't save nfo file " + self.nfofilename pos = self.nfo.find("MD5:") - if pos > 0 and len(self.nfo) >= pos+5+32: - self["statusbar"].text = _("Please wait for md5 signature verification...") + if pos > 0 and len(self.nfo) >= pos+5+32: + self["statusbar"].text = ("Please wait for md5 signature verification...") cmd = "md5sum -c -" md5 = self.nfo[pos+5:pos+5+32] + " " + self.nfilocal print cmd, md5 @@ -415,6 +417,8 @@ class NFIDownload(Screen): else: self["statusbar"].text = "Download completed." self.downloading(False) + if self.wizard_mode: + self.configBackup() def md5ready(self, retval): self.download_container.sendEOF() @@ -423,9 +427,12 @@ class NFIDownload(Screen): print "[md5finished]: " + str(retval) self.download_container.appClosed.remove(self.md5finished) if retval==0: - self["statusbar"].text = _(".NFI file passed md5sum signature check. You can safely flash this image!") - self.switchList(self.LIST_SOURCE) self.downloading(False) + if self.wizard_mode: + self.configBackup() + else: + self["statusbar"].text = _(".NFI file passed md5sum signature check. You can safely flash this image!") + self.switchList(self.LIST_SOURCE) else: self.session.openWithCallback(self.nfi_remove, MessageBox, (_("The md5sum validation failed, the file may be downloaded incompletely or be corrupted!") + "\n" + _("Remove the broken .NFI file?")), MessageBox.TYPE_YESNO) @@ -489,33 +496,22 @@ class NFIDownload(Screen): def umount_finished(self, retval): self.container.appClosed.remove(self.umount_finished) - self.session.openWithCallback(self.dmesg_clear, MessageBox, _("To make sure you intend to do this, please remove the target USB stick now and stick it back in upon prompt. Press OK when you have taken the stick out."), MessageBox.TYPE_INFO) - - def dmesg_clear(self, answer): self.container.appClosed.append(self.dmesg_cleared) self.taskstring = "" self.cmd = "dmesg -c" print "executing " + self.cmd self.container.execute(self.cmd) - def dmesg_cleared(self, retval): + def dmesg_cleared(self, answer): self.container.appClosed.remove(self.dmesg_cleared) - self.session.openWithCallback(self.stick_back_in, MessageBox, (_("Now please insert the USB stick (minimum size is 64 MB) that you want to format and use as .NFI image flasher. Press OK after you've put the stick back in.")), MessageBox.TYPE_INFO) - - def stick_back_in(self, answer): - self["statusbar"].text = _("Waiting for USB stick to settle...") - self.delayTimer = eTimer() - self.delayTimer.callback.append(self.waiting_for_stick) - self.delayCount = -1 - self.delayTimer.start(1000) - - def waiting_for_stick(self): - self.delayCount += 1 - self["job_progressbar"].range = 6 - self["job_progressbar"].value = self.delayCount - self["job_progresslabel"].text = "-%d s" % (6-self.delayCount) - if self.delayCount > 5: - self.delayTimer.stop() + self.msgbox = self.session.open(MessageBox, _("Please disconnect all USB devices from your Dreambox and (re-)attach the target USB stick (minimum size is 64 MB) now!"), MessageBox.TYPE_INFO) + hotplugNotifier.append(self.hotplugCB) + + def hotplugCB(self, dev, action): + print "[hotplugCB]", dev, action + if dev.startswith("sd") and action == "add": + self.msgbox.close() + hotplugNotifier.remove(self.hotplugCB) self.container.appClosed.append(self.dmesg_scanned) self.taskstring = "" self.cmd = "dmesg" @@ -539,8 +535,8 @@ class NFIDownload(Screen): self.session.openWithCallback(self.fdisk_query, MessageBox, (_("The following device was found:\n\n%s\n\nDo you want to write the USB flasher to this stick?") % self.devicetext), MessageBox.TYPE_YESNO) def fdisk_query(self, answer): - if answer == True: - self["statusbar"].text = _("Partitioning USB stick...") + if answer == True and self.stickdevice: + self["statusbar"].text = ("Partitioning USB stick...") self["job_progressbar"].range = 1000 self["job_progressbar"].value = 100 self["job_progresslabel"].text = "5.00%" @@ -562,7 +558,7 @@ class NFIDownload(Screen): self.tar_finished(0) self["job_progressbar"].value = 700 else: - self["statusbar"].text = _("Decompressing USB stick flasher boot image...") + self["statusbar"].text = ("Decompressing USB stick flasher boot image...") self.taskstring = "" self.container.appClosed.append(self.tar_finished) self.container.setCWD("/tmp") @@ -588,7 +584,7 @@ class NFIDownload(Screen): self.container.appClosed.remove(self.tar_finished) if retval == 0: self.imagefilename = "/tmp/nfiflash_" + self.box + ".img" - self["statusbar"].text = _("Copying USB flasher boot image to stick...") + self["statusbar"].text = ("Copying USB flasher boot image to stick...") self.taskstring = "" self.container.appClosed.append(self.dd_finished) self.cmd = "dd if=%s of=%s" % (self.imagefilename,self.stickdevice+"/part1") @@ -607,7 +603,7 @@ class NFIDownload(Screen): if retval == 0: self["job_progressbar"].value = 950 self["job_progresslabel"].text = "95.00%" - self["statusbar"].text = _("Remounting stick partition...") + self["statusbar"].text = ("Remounting stick partition...") self.taskstring = "" self.container.appClosed.append(self.mount_finished) self.cmd = "mount %s /mnt/usb -o rw,sync" % (self.stickdevice+"/part1") @@ -622,11 +618,12 @@ class NFIDownload(Screen): if retval == 0: self["job_progressbar"].value = 1000 self["job_progresslabel"].text = "100.00%" - self["statusbar"].text = _(".NFI Flasher bootable USB stick successfully created.") - self.session.openWithCallback(self.remove_img, MessageBox, _("The .NFI Image flasher USB stick is now ready to use. Please download an .NFI image file from the feed server and save it on the stick. Then reboot and hold the 'Down' key on the front panel to boot the .NFI flasher from the stick!"), MessageBox.TYPE_INFO) + self["statusbar"].text = (".NFI Flasher bootable USB stick successfully created.") + self.session.openWithCallback(self.flasherFinishedCB, MessageBox, _("The USB stick is now bootable. Do you want to download the latest image from the feed server and save it on the stick?"), type = MessageBox.TYPE_YESNO) self["destlist"].changeDir("/mnt/usb") else: - self.session.openWithCallback(self.remove_img, MessageBox, (self.cmd + " " + _("failed") + ":\n" + str(self.taskstring)), MessageBox.TYPE_ERROR) + self.session.openWithCallback(self.flasherFinishedCB, MessageBox, (self.cmd + " " + _("failed") + ":\n" + str(self.taskstring)), MessageBox.TYPE_ERROR) + self.remove_img(True) def remove_img(self, answer): if fileExists("/tmp/nfiflasher_image.tar.bz2"): @@ -636,6 +633,39 @@ class NFIDownload(Screen): self.downloading(False) self.switchList(self.LIST_SOURCE) + def flasherFinishedCB(self, answer): + if answer == True: + self.wizard_mode = True + self["feedlist"].moveSelection(0) + self["path_bottom"].text = str(self["destlist"].getCurrentDirectory()) + self.nfo_download() + self.nfi_download() + + def configBackup(self): + self.session.openWithCallback(self.runBackup, MessageBox, _("The wizard can backup your current settings. Do you want to do a backup now?")) + + def runBackup(self, result=None): + from Tools.Directories import createDir, isMount, pathExists + from time import localtime + from datetime import date + from Screens.Console import Console + if result: + if isMount("/mnt/usb/"): + if (pathExists("/mnt/usb/backup") == False): + createDir("/mnt/usb/backup", True) + d = localtime() + dt = date(d.tm_year, d.tm_mon, d.tm_mday) + self.backup_file = "backup/" + str(dt) + "_settings_backup.tar.gz" + self.session.open(Console, title = "Backup running", cmdlist = ["tar -czvf " + "/mnt/usb/" + self.backup_file + " /etc/enigma2/ /etc/network/interfaces /etc/wpa_supplicant.conf"], finishedCallback = self.backup_finished, closeOnSuccess = True) + + def backup_finished(self): + wizardfd = open("/mnt/usb/wizard.nfo", "w") + if wizardfd: + wizardfd.write("image: "+self["feedlist"].getNFIname()+'\n') + wizardfd.write("configuration: "+self.backup_file+'\n') + wizardfd.close() + self.session.open(MessageBox, _("To update your Dreambox firmware, please follow these steps:\n1) Turn off your box with the rear power switch and plug in the bootable USB stick.\n2) Turn mains back on and hold the DOWN button on the front panel pressed for 10 seconds.\n3) Wait for bootup and follow instructions of the wizard."), type = MessageBox.TYPE_INFO) + def closeCB(self): if self.download: self.download.stop() @@ -659,8 +689,8 @@ def filescan(**kwargs): Scanner(mimetypes = ["application/x-dream-image"], paths_to_scan = [ - ScanPath(path = "", with_subdirs = False), + ScanPath(path = "", with_subdirs = False), ], name = "NFI", - description = (_("Download .NFI-Files for USB-Flasher")+"..."), + description = (_("Download .NFI-Files for USB-Flasher")+"..."), openfnc = filescan_open, ) diff --git a/lib/python/Plugins/SystemPlugins/NFIFlash/flasher.py b/lib/python/Plugins/SystemPlugins/NFIFlash/flasher.py index 6a982c5..860efc0 100644 --- a/lib/python/Plugins/SystemPlugins/NFIFlash/flasher.py +++ b/lib/python/Plugins/SystemPlugins/NFIFlash/flasher.py @@ -17,7 +17,7 @@ import re class writeNAND(Task): def __init__(self,job,param,box): - Task.__init__(self,job, _("Writing image file to NAND Flash")) + Task.__init__(self,job, ("Writing image file to NAND Flash")) self.setTool("/usr/lib/enigma2/python/Plugins/SystemPlugins/NFIFlash/mywritenand") if box == "dm7025": self.end = 256 @@ -26,7 +26,7 @@ class writeNAND(Task): if box == "dm8000": self.setTool("/usr/lib/enigma2/python/Plugins/SystemPlugins/NFIFlash/dm8000_writenand") self.args += param - self.weighting = 1 + self.weighting = 1 def processOutput(self, data): print "[writeNand] " + data @@ -174,8 +174,8 @@ class NFIFlash(Screen): print sign if sign.find("NFI1" + self.box + "\0") == 0: if self.md5sum != "": - self["statusbar"].text = _("Please wait for md5 signature verification...") - self.session.summary.setText(_("Please wait for md5 signature verification...")) + self["statusbar"].text = ("Please wait for md5 signature verification...") + self.session.summary.setText(("Please wait for md5 signature verification...")) self.container = eConsoleAppContainer() self.container.setCWD(self["filelist"].getCurrentDirectory()) self.container.appClosed.append(self.md5finished) @@ -252,7 +252,7 @@ class NFIFlash(Screen): def reboot(self): if self.job.status == self.job.FINISHED: - self["statusbar"].text = _("rebooting...") + self["statusbar"].text = ("rebooting...") TryQuitMainloop(self.session,2) def createSummary(self): diff --git a/lib/python/Plugins/SystemPlugins/Videomode/VideoHardware.py b/lib/python/Plugins/SystemPlugins/Videomode/VideoHardware.py index 2422475..02fdf9a 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 = (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 = (16,10) + elif is_auto: + try: + aspect_str = open("/proc/stb/vmpeg/0/aspect", "r").read() + if aspect_str == "1": # 4:3 + ret = (4,3) + except IOError: + pass + else: # 4:3 + ret = (4,3) + 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) diff --git a/lib/python/Screens/Console.py b/lib/python/Screens/Console.py index b57f240..c6b156c 100644 --- a/lib/python/Screens/Console.py +++ b/lib/python/Screens/Console.py @@ -55,6 +55,7 @@ class Console(Screen): str = self["text"].getText() str += _("Execution finished!!"); self["text"].setText(str) + self["text"].lastPage() if self.finishedCallback is not None: self.finishedCallback() if not retval and self.closeOnSuccess: @@ -67,4 +68,4 @@ class Console(Screen): self.container.dataAvail.remove(self.dataAvail) def dataAvail(self, str): - self["text"].setText(self["text"].getText() + str) + self["text"].setText(self["text"].getText() + str) \ No newline at end of file diff --git a/lib/python/Screens/InfoBarGenerics.py b/lib/python/Screens/InfoBarGenerics.py index cdaa2c1..eb79c74 100644 --- a/lib/python/Screens/InfoBarGenerics.py +++ b/lib/python/Screens/InfoBarGenerics.py @@ -1312,7 +1312,6 @@ class InfoBarJobman: self.session.openWithCallback(self.JobViewCB, JobView, job) def JobViewCB(self, in_background): - from Screens.TaskView import JobView job_manager.in_background = in_background # depends on InfoBarExtensions diff --git a/lib/python/Tools/Directories.py b/lib/python/Tools/Directories.py index 2b60924..0d238b3 100644 --- a/lib/python/Tools/Directories.py +++ b/lib/python/Tools/Directories.py @@ -126,6 +126,9 @@ def resolveFilename(scope, base = "", path_prefix = None): def pathExists(path): return os_path.exists(path) +def isMount(path): + return os_path.ismount(path) + def createDir(path, makeParents = False): try: if makeParents: 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; diff --git a/po/de.po b/po/de.po index 7518643..70cd99f 100755 --- a/po/de.po +++ b/po/de.po @@ -7,8 +7,8 @@ msgid "" msgstr "" "Project-Id-Version: tuxbox-enigma 0.0.1\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2008-11-14 23:57+0100\n" -"PO-Revision-Date: 2008-11-14 23:41+0100\n" +"POT-Creation-Date: 2008-11-18 12:42+0100\n" +"PO-Revision-Date: 2008-11-18 13:00+0100\n" "Last-Translator: Andreas Frisch \n" "Language-Team: none\n" "MIME-Version: 1.0\n" @@ -743,9 +743,6 @@ msgstr "Abspielen fortsetzen" msgid "Contrast" msgstr "Kontrast" -msgid "Copying USB flasher boot image to stick..." -msgstr "" - msgid "Could not connect to Dreambox .NFI Image Feed Server:" msgstr "" @@ -822,9 +819,6 @@ msgstr "Dänisch" msgid "Date" msgstr "Datum" -msgid "Decompressing USB stick flasher boot image..." -msgstr "" - msgid "Deep Standby" msgstr "Ausschalten" @@ -858,7 +852,7 @@ msgid "Description" msgstr "Beschreibung" msgid "Destination directory" -msgstr "Zielverzeichniss" +msgstr "Zielverzeichnis" msgid "Detected HDD:" msgstr "Erkannte Festplatte:" @@ -1039,9 +1033,6 @@ msgstr "Herunterladbare Erweiterungen" msgid "Downloading" msgstr "Herunterladen" -msgid "Downloading image description..." -msgstr "" - msgid "Downloading plugin information. Please wait..." msgstr "Lade Plugin-Informationen herunter. Bitte warten..." @@ -1124,9 +1115,6 @@ msgstr "Passwortverschlüsselungstyp" msgid "Encryption Type" msgstr "Verschlüssellungsart" -msgid "End" -msgstr "Ende" - msgid "End time" msgstr "Endzeit" @@ -1269,12 +1257,8 @@ msgstr "Netzwerkneustart abgeschlossen" msgid "Finnish" msgstr "Finnisch" -msgid "" -"First we need to download the latest boot environment for the USB flasher." -msgstr "" - -msgid "Fix USB stick" -msgstr "" +msgid "First we need to download the latest boot environment for the USB flasher." +msgstr "Zuerst muss die neueste Bootumgebung für den USB-Flasher heruntergeladen werden." msgid "Flash" msgstr "" @@ -1863,7 +1847,7 @@ msgstr "" "Bitte die Tuner konfigurieren bevor die Kanalsuche gestartet wird." msgid "No useable USB stick found" -msgstr "" +msgstr "Kein nutzbarer USB-Stick gefunden" msgid "" "No valid service PIN found!\n" @@ -1994,9 +1978,6 @@ msgstr "" msgid "Orbital Position" msgstr "Orbitposition" -msgid "Other..." -msgstr "Andere..." - msgid "PAL" msgstr "PAL" @@ -2031,9 +2012,6 @@ msgstr "Jugendschutz-Einstellungen" msgid "Parental control type" msgstr "Jugendschutz-Typ" -msgid "Partitioning USB stick..." -msgstr "" - msgid "Pause movie at end" msgstr "Am Filmende pausieren" @@ -2081,8 +2059,10 @@ msgid "Please choose he package..." msgstr "Bitte wählen Sie das Paket aus..." msgid "Please choose the default services lists you want to install." -msgstr "" -"Bitte wählen Sie die Standard-Kanallisten, die Sie installieren wollen." +msgstr "Bitte wählen Sie die Standard-Kanallisten, die Sie installieren wollen." + +msgid "Please disconnect all USB devices from your Dreambox and (re-)attach the target USB stick (minimum size is 64 MB) now!" +msgstr "Bitte ziehen Sie jetzt alle USB-Geräte von Ihrer Dreambox ab und stecken (erneut) den zu benutzenden USB-Stick (Mindestgrößte von 64 MB) ein!" msgid "Please do not change any values unless you know what you are doing!" msgstr "Bitte ändern Sie keine Werte, falls Sie nicht wissen, was Sie tun!" @@ -2174,9 +2154,6 @@ msgstr "" msgid "Please wait for activation of your network configuration..." msgstr "Bitte warten während die Netzwerkkonfiguration aktiviert wird..." -msgid "Please wait for md5 signature verification..." -msgstr "" - msgid "Please wait while we configure your network..." msgstr "Bitte warten während das Netzwerk konfiguriert wird..." @@ -2357,9 +2334,6 @@ msgstr "Bildwiederholrate" msgid "Refresh rate selection." msgstr "Auswahl der Bildwiederholungsrate." -msgid "Remounting stick partition..." -msgstr "" - msgid "Remove Bookmark" msgstr "Bookmark entfernen" @@ -2853,9 +2827,6 @@ msgstr "Standby" msgid "Standby / Restart" msgstr "Standby / Neustart" -msgid "Start" -msgstr "Start" - msgid "Start from the beginning" msgstr "Am Anfang starten" @@ -2978,21 +2949,11 @@ msgstr "" "Der Assistent ist hiermit beendet. Ihre Dreambox kann nun benutzt werden.\n" "Bitte drücken Sie OK, um den Assistenten zu verlassen." -msgid "" -"The .NFI Image flasher USB stick is now ready to use. Please download an ." -"NFI image file from the feed server and save it on the stick. Then reboot " -"and hold the 'Down' key on the front panel to boot the .NFI flasher from the " -"stick!" -msgstr "" +msgid "The DVD standard doesn't support H.264 (HDTV) video streams. Do you want to create a Dreambox format data DVD (which will not play in stand-alone DVD players) instead?" +msgstr "Der DVD-Standard unterstützt keine H.264 (HDTV) Videos. Soll stattdessen eine Daten-DVD im Dreambox-Format (die nicht in einem herkömmlichen DVD-Player abspielbar ist) erstellt werden?" -msgid "" -"The DVD standard doesn't support H.264 (HDTV) video streams. Do you want to " -"create a Dreambox format data DVD (which will not play in stand-alone DVD " -"players) instead?" -msgstr "" -"Der DVD-Standard unterstützt keine H.264 (HDTV) Videos. Soll stattdessen " -"eine Daten-DVD im Dreambox-Format (die nicht in einem herkömmlichen DVD-" -"Player abspielbar ist) erstellt werden?" +msgid "The USB stick is now bootable. Do you want to download the latest image from the feed server and save it on the stick?" +msgstr "Der USB-Stick ist nun bootfähig. Wollen Sie das neueste Image vom Update-Server herunterladen und auf dem Stick speichern?" msgid "The backup failed. Please choose a different backup location." msgstr "" @@ -3007,6 +2968,11 @@ msgid "" "\n" "Do you want to write the USB flasher to this stick?" msgstr "" +"Das folgende Medium wurde gefunden:\n" +"\n" +"%s\n" +"\n" +"Soll der USB-Flasher auf diesen Stick installiert werden?" msgid "" "The input port should be configured now.\n" @@ -3257,9 +3223,15 @@ msgid "Titleset mode" msgstr "Titleset" msgid "" -"To make sure you intend to do this, please remove the target USB stick now " -"and stick it back in upon prompt. Press OK when you have taken the stick out." +"To update your Dreambox firmware, please follow these steps:\n" +"1) Turn off your box with the rear power switch and plug in the bootable USB stick.\n" +"2) Turn mains back on and hold the DOWN button on the front panel pressed for 10 seconds.\n" +"3) Wait for bootup and follow instructions of the wizard." msgstr "" +"Um Ihre Dreambox-Firmware zu aktualisieren, folgen Sie bitte diesen Anweisungen:\n" +"1) Schalten Sie Ihre Dreambox mit dem Schalter auf der Rückseite aus und stecken Sie den bootfähigen USB-Stick ein.\n" +"2) Schalten Sie den Netzschalter wieder ein und halten dabei den \"nach unten\"-Knopf auf der Vorderseite für 10 Sekunden gedrückt.\n" +"3) Nach dem Bootvorgang folgen Sie bitten den Instruktionen des Assistenten." msgid "Today" msgstr "Heute" @@ -3348,6 +3320,12 @@ msgstr "USB" msgid "USB Stick" msgstr "USB-Stick" +msgid "USB stick wizard" +msgstr "" + +msgid "Ukrainian" +msgstr "" + msgid "" "Unable to complete filesystem check.\n" "Error: " @@ -3533,9 +3511,6 @@ msgstr "WSS bei 4:3" msgid "Waiting" msgstr "Warte" -msgid "Waiting for USB stick to settle..." -msgstr "" - msgid "" "We will now test if your TV can also display this resolution at 50hz. If " "your screen goes black, wait 20 seconds and it will switch back to 60hz.\n" @@ -3613,9 +3588,6 @@ msgstr "Schreiben fehlgeschlagen!" msgid "Writing NFI image file to flash completed" msgstr "" -msgid "Writing image file to NAND Flash" -msgstr "" - msgid "YPbPr" msgstr "YPbPr" @@ -3924,9 +3896,6 @@ msgstr "Negativliste" msgid "burn audio track (%s)" msgstr "Brenne die Audiospur (%s)" -msgid "by Exif" -msgstr "" - msgid "change recording (duration)" msgstr "Aufnahme ändern (Aufnahmelänge)" @@ -4429,10 +4398,10 @@ msgid "select" msgstr "wähle" msgid "select .NFI flash file" -msgstr "Wähle eine .NFI Flashdatei" +msgstr "Wähle Sie eine .NFI Flashdatei" msgid "select image from server" -msgstr "Wähle ein Image vom Server" +msgstr "Wähle Sie ein Image vom Server" msgid "select interface" msgstr "Wähle einen Netzwerkadapter"