-#include "picload.h"
+#include <png.h> // must be included before Python.h because of setjmp
+#include <lib/gdi/picload.h>
#include "picexif.h"
-
-#include <png.h>
+#include <lib/python/python.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
+#include <epng.h> // savePNG need it
+
+#define JDCT_DEFAULT JDCT_IFAST
+
extern "C" {
#include <jpeglib.h>
+#include <gif_lib.h>
//#include "transupp.h"
}
-#include <setjmp.h>
unsigned char *pic_buffer=NULL;
+static unsigned char *conv24to32(unsigned char * orgin, int size, int background = 0)
+{
+ int s, d;
+ unsigned char *cr = new unsigned char[size * 4];
+ if (cr == NULL)
+ {
+ printf("[CONV32] Error: malloc\n");
+ 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];
+ cr[d+1] = orgin[s + 1];
+ cr[d+2] = orgin[s + 2];
+ cr[d+3] = alpha;
+ }
+ delete [] orgin;
+ return(cr);
+}
+
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 * 3];
+ cr = new unsigned char[dx * dy * 4];
if (cr == NULL)
{
printf("[RESIZE] Error: malloc\n");
}
l = cr;
- for (j = 0; j < dy; j++,l += dx * 3)
+ for (j = 0; j < dy; j++,l += dx * 4)
{
- p = orgin + (j * oy / dy * ox * 3);
- for (i = 0, k = 0; i < dx; i++, k += 3)
+ p = orgin + (j * oy / dy * ox * 4);
+ for (i = 0, k = 0; i < dx; i++, k += 4)
{
- ip = i * ox / dx * 3;
+ ip = i * ox / dx * 4;
l[k] = p[ip];
l[k+1] = p[ip + 1];
l[k+2] = p[ip + 2];
+ l[k+3] = p[ip + 3];
}
}
delete [] orgin;
{
unsigned char *cr, *p, *q;
int i, j, k, l, xa, xb, ya, yb;
- int sq, r, g, b;
- cr = new unsigned char[dx * dy * 3];
+ int sq, r, g, b, a;
+ cr = new unsigned char[dx * dy * 4];
if (cr == NULL)
{
printf("[RESIZE] Error: malloc\n");
for (j = 0; j < dy; j++)
{
- for (i = 0; i < dx; i++, p += 3)
+ for (i = 0; i < dx; i++, p += 4)
{
xa = i * ox / dx;
ya = j * oy / dy;
yb = (j + 1) * oy / dy;
if (yb >= oy)
yb = oy - 1;
- for (l = ya, r = 0, g = 0, b = 0, sq = 0; l <= yb; l++)
+ for (l = ya, r = 0, g = 0, b = 0, a = 0, sq = 0; l <= yb; l++)
{
- q = orgin + ((l * ox + xa) * 3);
- for (k = xa; k <= xb; k++, q += 3, sq++)
+ q = orgin + ((l * ox + xa) * 4);
+ for (k = xa; k <= xb; k++, q += 4, sq++)
{
- r += q[0]; g += q[1]; b += q[2];
+ r += q[0]; g += q[1]; b += q[2]; a += q[3];
}
}
- p[0] = r / sq; p[1] = g / sq; p[2] = b / sq;
+ p[0] = r / sq; p[1] = g / sq; p[2] = b / sq; p[3] = a / sq;
}
}
delete [] orgin;
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)
{
#define fill4B(a) ((4 - ((a) % 4 )) & 0x03)
+struct color {
+ unsigned char red;
+ unsigned char green;
+ unsigned char blue;
+};
+
+static void fetch_pallete(int fd, struct color pallete[], int count)
+{
+ unsigned char buff[4];
+ lseek(fd, BMP_COLOR_OFFSET, SEEK_SET);
+ for (int i = 0; i < count; i++)
+ {
+ read(fd, buff, 4);
+ pallete[i].red = buff[2];
+ pallete[i].green = buff[1];
+ pallete[i].blue = buff[0];
+ }
+}
+
static int bmp_load(const char *filename, int *x, int *y)
{
unsigned char buff[4];
+ struct color pallete[256];
int fd = open(filename, O_RDONLY);
if (fd == -1) return 0;
read(fd, buff, 2);
int bpp = buff[0] + (buff[1] << 8);
- //printf("x=%d, y=%d,bpp=%d\n",*x, *y, bpp);
pic_buffer = new unsigned char[(*x) * (*y) * 3];
unsigned char *wr_buffer = pic_buffer + (*x) * ((*y) - 1) * 3;
switch (bpp)
{
+ case 4:
+ {
+ int skip = fill4B((*x) / 2 + (*x) % 2);
+ fetch_pallete(fd, pallete, 16);
+ lseek(fd, raster, SEEK_SET);
+ unsigned char * tbuffer = new unsigned char[*x / 2 + 1];
+ if (tbuffer == NULL)
+ return 0;
+ for (int i = 0; i < *y; i++)
+ {
+ read(fd, tbuffer, (*x) / 2 + *x % 2);
+ int j;
+ for (j = 0; j < (*x) / 2; j++)
+ {
+ unsigned char c1 = tbuffer[j] >> 4;
+ unsigned char c2 = tbuffer[j] & 0x0f;
+ *wr_buffer++ = pallete[c1].red;
+ *wr_buffer++ = pallete[c1].green;
+ *wr_buffer++ = pallete[c1].blue;
+ *wr_buffer++ = pallete[c2].red;
+ *wr_buffer++ = pallete[c2].green;
+ *wr_buffer++ = pallete[c2].blue;
+ }
+ if ((*x) % 2)
+ {
+ unsigned char c1 = tbuffer[j] >> 4;
+ *wr_buffer++ = pallete[c1].red;
+ *wr_buffer++ = pallete[c1].green;
+ *wr_buffer++ = pallete[c1].blue;
+ }
+ if (skip)
+ read(fd, buff, skip);
+ wr_buffer -= (*x) * 6;
+ }
+ break;
+ }
+ case 8:
+ {
+ int skip = fill4B(*x);
+ fetch_pallete(fd, pallete, 256);
+ lseek(fd, raster, SEEK_SET);
+ unsigned char * tbuffer = new unsigned char[*x];
+ if (tbuffer == NULL)
+ return 0;
+ for (int i = 0; i < *y; i++)
+ {
+ read(fd, tbuffer, *x);
+ for (int j = 0; j < *x; j++)
+ {
+ wr_buffer[j * 3] = pallete[tbuffer[j]].red;
+ wr_buffer[j * 3 + 1] = pallete[tbuffer[j]].green;
+ wr_buffer[j * 3 + 2] = pallete[tbuffer[j]].blue;
+ }
+ if (skip)
+ read(fd, buff, skip);
+ wr_buffer -= (*x) * 3;
+ }
+ break;
+ }
case 24:
{
int skip = fill4B((*x) * 3);
lseek(fd, raster, SEEK_SET);
- unsigned char c;
- for (int i = 0; i < (*y); i++)
+ for (int i = 0; i < (*y); i++)
{
read(fd, wr_buffer, (*x) * 3);
for (int j = 0; j < (*x) * 3 ; j = j + 3)
{
- c = wr_buffer[j];
+ unsigned char c = wr_buffer[j];
wr_buffer[j] = wr_buffer[j + 2];
wr_buffer[j + 2] = c;
}
}
//---------------------------------------------------------------------------------------------
-
static int png_load(const char *filename, int *x, int *y)
{
static const png_color_16 my_background = {0, 0, 0, 0, 0};
png_read_info(png_ptr, info_ptr);
png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, &interlace_type, NULL, NULL);
- if (color_type == PNG_COLOR_TYPE_PALETTE)
- {
- png_set_palette_to_rgb(png_ptr);
- png_set_background(png_ptr, (png_color_16 *)&my_background, PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0);
- }
-
+ if ((color_type == PNG_COLOR_TYPE_PALETTE)||(color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8)||(png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)))
+ png_set_expand(png_ptr);
+ if (bit_depth == 16)
+ png_set_strip_16(png_ptr);
if (color_type == PNG_COLOR_TYPE_GRAY || color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
- {
png_set_gray_to_rgb(png_ptr);
- png_set_background(png_ptr, (png_color_16 *)&my_background, PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0);
- }
-
- if (color_type & PNG_COLOR_MASK_ALPHA)
- png_set_strip_alpha(png_ptr);
-
- if (bit_depth < 8) png_set_packing(png_ptr);
- if (bit_depth == 16) png_set_strip_16(png_ptr);
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))
+ int bpp = png_get_rowbytes(png_ptr, info_ptr)/width;
+ if ((bpp !=4) && (bpp !=3))
{
eDebug("[PNG] Error processing");
return 0;
}
-
- pic_buffer = new unsigned char[width * height * 3];
+
+ if (width * height > 1000000) // 1000x1000 or equiv.
+ {
+ eDebug("[png_load] image size is %d x %d, which is \"too large\".", (int)width, (int)height);
+ png_read_end(png_ptr, info_ptr);
+ png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL);
+ fclose(fh);
+ return 0;
+ }
+
+ pic_buffer = new unsigned char[width * height * bpp];
*x=width;
*y=height;
for(pass = 0; pass < number_passes; pass++)
{
fbptr = (png_byte *)pic_buffer;
- for (i = 0; i < height; i++, fbptr += width * 3)
+ for (i = 0; i < height; i++, fbptr += width * bpp)
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;
}
+//-------------------------------------------------------------------
+
+inline void m_rend_gif_decodecolormap(unsigned char *cmb, unsigned char *rgbb, ColorMapObject *cm, int s, int l)
+{
+ GifColorType *cmentry;
+ int i;
+ for (i = 0; i < l; i++)
+ {
+ cmentry = &cm->Colors[cmb[i]];
+ *(rgbb++) = cmentry->Red;
+ *(rgbb++) = cmentry->Green;
+ *(rgbb++) = cmentry->Blue;
+ }
+}
+
+static int gif_load(const char *filename, int *x, int *y)
+{
+ int px, py, i, j, ibxs;
+ unsigned char *fbptr;
+ unsigned char *lb=NULL;
+ unsigned char *slb=NULL;
+ GifFileType *gft;
+ GifRecordType rt;
+ GifByteType *extension;
+ ColorMapObject *cmap;
+ int cmaps;
+ int extcode;
+
+ gft = DGifOpenFileName(filename);
+ if (gft == NULL)
+ return 0;
+ do
+ {
+ if (DGifGetRecordType(gft, &rt) == GIF_ERROR)
+ goto ERROR_R;
+ switch(rt)
+ {
+ case IMAGE_DESC_RECORD_TYPE:
+ if (DGifGetImageDesc(gft) == GIF_ERROR)
+ goto ERROR_R;
+ *x = px = gft->Image.Width;
+ *y = py = gft->Image.Height;
+ pic_buffer = new unsigned char[px * py * 3];
+ lb = (unsigned char *)malloc(px * 3);
+ slb = (unsigned char *) malloc(px);
+
+ if (lb != NULL && slb != NULL)
+ {
+ cmap = (gft->Image.ColorMap ? gft->Image.ColorMap : gft->SColorMap);
+ cmaps = cmap->ColorCount;
+
+ ibxs = ibxs * 3;
+ fbptr = pic_buffer;
+ if (!(gft->Image.Interlace))
+ {
+ for (i = 0; i < py; i++, fbptr += px * 3)
+ {
+ if (DGifGetLine(gft, slb, px) == GIF_ERROR)
+ goto ERROR_R;
+ m_rend_gif_decodecolormap(slb, lb, cmap, cmaps, px);
+ memcpy(fbptr, lb, px * 3);
+ }
+ }
+ else
+ {
+ for (j = 0; j < 4; j++)
+ {
+ fbptr = pic_buffer;
+ for (i = 0; i < py; i++, fbptr += px * 3)
+ {
+ if (DGifGetLine(gft, slb, px) == GIF_ERROR)
+ goto ERROR_R;
+ m_rend_gif_decodecolormap(slb, lb, cmap, cmaps, px);
+ memcpy(fbptr, lb, px * 3);
+ }
+ }
+ }
+ }
+ if (lb)
+ {
+ free(lb);
+ lb=NULL;
+ }
+ if (slb)
+ {
+ free(slb);
+ slb=NULL;
+ }
+ break;
+ case EXTENSION_RECORD_TYPE:
+ if (DGifGetExtension(gft, &extcode, &extension) == GIF_ERROR)
+ goto ERROR_R;
+ while (extension != NULL)
+ if (DGifGetExtensionNext(gft, &extension) == GIF_ERROR)
+ goto ERROR_R;
+ break;
+ default:
+ break;
+ }
+ }
+ while (rt != TERMINATE_RECORD_TYPE);
+
+ DGifCloseFile(gft);
+ return 1;
+ERROR_R:
+ eDebug("[GIF] Error");
+ if (lb) free(lb);
+ if (slb) free(slb);
+ DGifCloseFile(gft);
+ return 0;
+}
+
//---------------------------------------------------------------------------------------------
PyObject *getExif(const char *filename)
{
- PyObject *list = 0;
- Cexif *m_exif = new Cexif();
- if(m_exif->DecodeExif(filename))
+ ePyObject list;
+ Cexif exif;
+ if(exif.DecodeExif(filename))
{
- if(m_exif->m_exifinfo->IsExif)
+ if(exif.m_exifinfo->IsExif)
{
int pos=0;
char tmp[256];
list = PyList_New(22);
- PyList_SET_ITEM(list, pos++, PyString_FromString(m_exif->m_exifinfo->Version));
- PyList_SET_ITEM(list, pos++, PyString_FromString(m_exif->m_exifinfo->CameraMake));
- PyList_SET_ITEM(list, pos++, PyString_FromString(m_exif->m_exifinfo->CameraModel));
- PyList_SET_ITEM(list, pos++, PyString_FromString(m_exif->m_exifinfo->DateTime));
- PyList_SET_ITEM(list, pos++, PyString_FromString(m_exif->m_exifinfo->Comments));
- PyList_SET_ITEM(list, pos++, PyString_FromFormat("%d x %d", m_exif->m_exifinfo->Width, m_exif->m_exifinfo->Height));
- PyList_SET_ITEM(list, pos++, PyString_FromString(m_exif->m_exifinfo->Orientation));
- PyList_SET_ITEM(list, pos++, PyString_FromString(m_exif->m_exifinfo->MeteringMode));
- PyList_SET_ITEM(list, pos++, PyString_FromString(m_exif->m_exifinfo->ExposureProgram));
- PyList_SET_ITEM(list, pos++, PyString_FromString(m_exif->m_exifinfo->LightSource));
- PyList_SET_ITEM(list, pos++, PyString_FromString(m_exif->m_exifinfo->FlashUsed));
- PyList_SET_ITEM(list, pos++, PyString_FromFormat("%d", m_exif->m_exifinfo->CompressionLevel));
- PyList_SET_ITEM(list, pos++, PyString_FromFormat("%d", m_exif->m_exifinfo->ISOequivalent));
- sprintf(tmp, "%.2f", m_exif->m_exifinfo->Xresolution);
+ 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", m_exif->m_exifinfo->Yresolution);
+ sprintf(tmp, "%.2f", exif.m_exifinfo->Yresolution);
PyList_SET_ITEM(list, pos++, PyString_FromString(tmp));
- PyList_SET_ITEM(list, pos++, PyString_FromString(m_exif->m_exifinfo->ResolutionUnit));
- sprintf(tmp, "%.2f", m_exif->m_exifinfo->Brightness);
+ 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.", m_exif->m_exifinfo->ExposureTime);
+ sprintf(tmp, "%.5f sec.", exif.m_exifinfo->ExposureTime);
PyList_SET_ITEM(list, pos++, PyString_FromString(tmp));
- sprintf(tmp, "%.5f", m_exif->m_exifinfo->ExposureBias);
+ sprintf(tmp, "%.5f", exif.m_exifinfo->ExposureBias);
PyList_SET_ITEM(list, pos++, PyString_FromString(tmp));
- sprintf(tmp, "%.5f", m_exif->m_exifinfo->Distance);
+ sprintf(tmp, "%.5f", exif.m_exifinfo->Distance);
PyList_SET_ITEM(list, pos++, PyString_FromString(tmp));
- sprintf(tmp, "%.5f", m_exif->m_exifinfo->CCDWidth);
+ sprintf(tmp, "%.5f", exif.m_exifinfo->CCDWidth);
PyList_SET_ITEM(list, pos++, PyString_FromString(tmp));
- sprintf(tmp, "%.2f", m_exif->m_exifinfo->ApertureFNumber);
+ sprintf(tmp, "%.2f", exif.m_exifinfo->ApertureFNumber);
PyList_SET_ITEM(list, pos++, PyString_FromString(tmp));
}
else
{
list = PyList_New(1);
- PyList_SET_ITEM(list, 0, PyString_FromString(m_exif->m_szLastError));
+ PyList_SET_ITEM(list, 0, PyString_FromString(exif.m_szLastError));
}
- m_exif->ClearExif();
+ exif.ClearExif();
}
else
{
list = PyList_New(1);
- PyList_SET_ITEM(list, 0, PyString_FromString(m_exif->m_szLastError));
+ PyList_SET_ITEM(list, 0, PyString_FromString(exif.m_szLastError));
}
- delete m_exif;
-
- return list ? list : PyList_New(0);
+ return list ? (PyObject*)list : (PyObject*)PyList_New(0);
}
//---------------------------------------------------------------------------------------------
+enum {F_NONE, F_PNG, F_JPEG, F_BMP, F_GIF};
+
+static int pic_id(const char *name)
+{
+ unsigned char id[10];
+ int fd = open(name, O_RDONLY);
+ if (fd == -1)
+ return F_NONE;
+ read(fd, id, 10);
+ close(fd);
-int loadPic(ePtr<gPixmap> &result, std::string filename, int w, int h, int aspect, int resize_mode, int rotate, int background, std::string cachefile)
+ 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;
+}
+
+int loadPic(ePtr<gPixmap> &result, std::string filename, int w, int h, int aspect, int resize_mode, int rotate, int background, std::string cachefile, int thumbnail)
{
result = 0;
int ox=0, oy=0, imx, imy;
if(cachefile.length())
{
- cache = true;
- if(jpeg_load(cachefile.c_str(), &ox, &oy))
+ if(png_load(cachefile.c_str(), &ox, &oy))
eDebug("[CACHEPIC] x-size=%d, y-size=%d", ox, oy);
}
if(pic_buffer==NULL)
{
- unsigned int pos = filename.find_last_of(".");
- if (pos == std::string::npos)
- pos = filename.length() - 1;
- std::string ext = filename.substr(pos);
- std::transform(ext.begin(), ext.end(), ext.begin(), (int(*)(int)) toupper);
- if(ext == ".JPEG" || ext == ".JPG")
- jpeg_load(filename.c_str(), &ox, &oy);
- else if(ext == ".BMP")
- bmp_load(filename.c_str(), &ox, &oy);
- else if(ext == ".PNG")
- png_load(filename.c_str(), &ox, &oy);
- else
+ switch(pic_id(filename.c_str()))
{
- eDebug("[PIC] <format not supportet>");
- return 0;
+ 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] <format not supportet>");
+ return 0;
}
- eDebug("[FULLPIC] x-size=%d, y-size=%d", ox, oy);
-
if(pic_buffer==NULL)
return 0;
double aspect_ratio;
switch(aspect)
{
- case 1: aspect_ratio = 1.777 / ((double)720/576); break; //16:9
+ 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
+ case 3: aspect_ratio = 1.250 / ((double)720/576); break; //5:4
default: aspect_ratio = 1.333 / ((double)720/576); //4:3
}
ox = imx;
oy = imy;
-
- if(cache)
- {
- jpeg_save(pic_buffer, cachefile.c_str(), 50, oy, ox);
- eDebug("[SAVEPIC] x-size=%d, y-size=%d", ox, oy);
- }
-
}
-
+ else cache = true;
result=new gPixmap(eSize(w, h), 32);
gSurface *surface = result->surface;
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 = new unsigned char[4];
+ unsigned char *tmp_buffer=((unsigned char *)(surface->data));
if(oy < h)
{
//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)+1; a++, nc+=4)
+ for(a=0; a<(o_y*ox); a++, nc+=4)
{
- memcpy(tmp_buffer, clear, sizeof(clear));
tmp_buffer=((unsigned char *)(surface->data)) + nc;
+ memcpy(tmp_buffer, clear, sizeof(clear));
}
-
+
for(a=0; a<oy; a++)
{
if(ox < w)
for(b=0; b<v_x; b++, nc+=4)
{
- memcpy(tmp_buffer, clear, sizeof(clear));
tmp_buffer=((unsigned char *)(surface->data)) + nc;
+ memcpy(tmp_buffer, clear, sizeof(clear));
}
- for(b=0; b<(ox*3); b+=3, nc+=4)
+ for(b=0; b<(ox*4); b+=4, nc+=4)
{
- tmp_buffer[3]=0xFF;
+ 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=((unsigned char *)(surface->data)) + nc;
}
if(ox < w)
for(b=0; b<h_x; b++, nc+=4)
{
- memcpy(tmp_buffer, clear, sizeof(clear));
tmp_buffer=((unsigned char *)(surface->data)) + nc;
+ memcpy(tmp_buffer, clear, sizeof(clear));
}
}
if(oy < h)
- for(a=0; a<(u_y*ox)+1; a++, nc+=4)
+ for(a=0; a<(u_y*ox); a++, nc+=4)
{
- memcpy(tmp_buffer, clear, sizeof(clear));
tmp_buffer=((unsigned char *)(surface->data)) + nc;
+ memcpy(tmp_buffer, clear, sizeof(clear));
}
//eDebug("[PIC] buffer=%d, nc=%d oc=%d ox=%d, oy=%d",w*h*4, nc, oc, ox, oy);
delete [] pic_buffer;
+ if(cachefile.length() && !cache)
+ {
+ savePNG( cachefile.c_str(), result);
+ eDebug("[SAVEPIC] x-size=%d, y-size=%d", ox, oy);
+ }
+
return 0;
}