2008-11-05 09:21:04 -08:00
|
|
|
#ifdef HAVE_CONFIG_H
|
|
|
|
# include <config.h>
|
|
|
|
#endif
|
2006-10-27 20:02:23 -07:00
|
|
|
|
2006-01-14 12:03:42 -08:00
|
|
|
#include <stdio.h>
|
|
|
|
|
2008-11-05 09:21:04 -08:00
|
|
|
#ifdef HAVE_EVIL
|
|
|
|
# include <Evil.h>
|
|
|
|
#endif
|
|
|
|
|
2011-05-22 23:45:19 -07:00
|
|
|
#include <setjmp.h>
|
|
|
|
#include <jpeglib.h>
|
|
|
|
|
2008-11-05 09:21:04 -08:00
|
|
|
#include "evas_common.h"
|
|
|
|
#include "evas_private.h"
|
|
|
|
|
2006-01-14 12:03:42 -08:00
|
|
|
|
|
|
|
typedef struct _JPEG_error_mgr *emptr;
|
|
|
|
struct _JPEG_error_mgr
|
|
|
|
{
|
|
|
|
struct jpeg_error_mgr pub;
|
|
|
|
jmp_buf setjmp_buffer;
|
|
|
|
};
|
|
|
|
|
|
|
|
static void _JPEGFatalErrorHandler(j_common_ptr cinfo);
|
|
|
|
static void _JPEGErrorHandler(j_common_ptr cinfo);
|
|
|
|
static void _JPEGErrorHandler2(j_common_ptr cinfo, int msg_level);
|
|
|
|
|
2011-06-07 06:34:18 -07:00
|
|
|
static Eina_Bool evas_image_load_file_head_jpeg_internal(Image_Entry *ie,
|
|
|
|
void *map,
|
|
|
|
size_t len,
|
2011-11-11 00:11:16 -08:00
|
|
|
int *error) EINA_ARG_NONNULL(1, 2, 4);
|
2011-06-07 06:34:18 -07:00
|
|
|
static Eina_Bool evas_image_load_file_data_jpeg_internal(Image_Entry *ie,
|
|
|
|
void *map,
|
|
|
|
size_t len,
|
2011-11-11 00:11:16 -08:00
|
|
|
int *error) EINA_ARG_NONNULL(1, 2, 4);
|
2006-01-14 12:03:42 -08:00
|
|
|
#if 0 /* not used at the moment */
|
2009-12-22 15:11:57 -08:00
|
|
|
static int evas_image_load_file_data_jpeg_alpha_internal(Image_Entry *ie, FILE *f) EINA_ARG_NONNULL(1, 2);
|
2006-01-14 12:03:42 -08:00
|
|
|
#endif
|
|
|
|
|
2009-12-22 15:11:57 -08:00
|
|
|
static Eina_Bool evas_image_load_file_head_jpeg(Image_Entry *ie, const char *file, const char *key, int *error) EINA_ARG_NONNULL(1, 2, 4);
|
|
|
|
static Eina_Bool evas_image_load_file_data_jpeg(Image_Entry *ie, const char *file, const char *key, int *error) EINA_ARG_NONNULL(1, 2, 4);
|
2006-01-14 12:03:42 -08:00
|
|
|
|
2009-06-16 06:01:36 -07:00
|
|
|
static Evas_Image_Load_Func evas_image_load_jpeg_func =
|
2006-01-14 12:03:42 -08:00
|
|
|
{
|
2009-12-24 05:15:34 -08:00
|
|
|
EINA_TRUE,
|
2006-01-14 12:03:42 -08:00
|
|
|
evas_image_load_file_head_jpeg,
|
2011-08-10 23:04:08 -07:00
|
|
|
evas_image_load_file_data_jpeg,
|
2011-12-13 08:58:20 -08:00
|
|
|
NULL,
|
|
|
|
EINA_TRUE
|
2006-01-14 12:03:42 -08:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
_JPEGFatalErrorHandler(j_common_ptr cinfo)
|
|
|
|
{
|
|
|
|
emptr errmgr;
|
|
|
|
|
|
|
|
errmgr = (emptr) cinfo->err;
|
|
|
|
/* cinfo->err->output_message(cinfo);*/
|
|
|
|
longjmp(errmgr->setjmp_buffer, 1);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2009-10-22 15:33:06 -07:00
|
|
|
_JPEGErrorHandler(j_common_ptr cinfo __UNUSED__)
|
2006-01-14 12:03:42 -08:00
|
|
|
{
|
2009-10-22 15:33:06 -07:00
|
|
|
/* emptr errmgr; */
|
2006-01-14 12:03:42 -08:00
|
|
|
|
2009-10-22 15:33:06 -07:00
|
|
|
/* errmgr = (emptr) cinfo->err; */
|
2006-01-14 12:03:42 -08:00
|
|
|
/* cinfo->err->output_message(cinfo);*/
|
|
|
|
/* longjmp(errmgr->setjmp_buffer, 1);*/
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2009-10-22 15:33:06 -07:00
|
|
|
_JPEGErrorHandler2(j_common_ptr cinfo __UNUSED__, int msg_level __UNUSED__)
|
2006-01-14 12:03:42 -08:00
|
|
|
{
|
2009-10-22 15:33:06 -07:00
|
|
|
/* emptr errmgr; */
|
2006-01-14 12:03:42 -08:00
|
|
|
|
2009-10-22 15:33:06 -07:00
|
|
|
/* errmgr = (emptr) cinfo->err; */
|
2006-01-14 12:03:42 -08:00
|
|
|
/* cinfo->err->output_message(cinfo);*/
|
|
|
|
/* longjmp(errmgr->setjmp_buffer, 1);*/
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2011-06-07 06:34:18 -07:00
|
|
|
struct jpeg_membuf_src
|
|
|
|
{
|
|
|
|
struct jpeg_source_mgr pub;
|
|
|
|
|
|
|
|
const unsigned char *buf;
|
|
|
|
size_t len;
|
|
|
|
struct jpeg_membuf_src *self;
|
|
|
|
};
|
|
|
|
|
|
|
|
static void
|
|
|
|
_evas_jpeg_membuf_src_init(j_decompress_ptr cinfo __UNUSED__)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
static boolean
|
|
|
|
_evas_jpeg_membuf_src_fill(j_decompress_ptr cinfo)
|
|
|
|
{
|
|
|
|
static const JOCTET jpeg_eoi[2] = { 0xFF, JPEG_EOI };
|
|
|
|
struct jpeg_membuf_src *src = (struct jpeg_membuf_src *)cinfo->src;
|
|
|
|
|
|
|
|
src->pub.bytes_in_buffer = sizeof(jpeg_eoi);
|
|
|
|
src->pub.next_input_byte = jpeg_eoi;
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_evas_jpeg_membuf_src_skip(j_decompress_ptr cinfo,
|
2011-08-18 23:58:33 -07:00
|
|
|
long num_bytes)
|
2011-06-07 06:34:18 -07:00
|
|
|
{
|
|
|
|
struct jpeg_membuf_src *src = (struct jpeg_membuf_src *)cinfo->src;
|
|
|
|
|
2011-08-18 23:58:33 -07:00
|
|
|
if ((((long)src->pub.bytes_in_buffer - (long)src->len) > num_bytes) ||
|
|
|
|
((long)src->pub.bytes_in_buffer < num_bytes))
|
2011-07-10 19:29:16 -07:00
|
|
|
{
|
|
|
|
(*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo));
|
2011-08-18 23:58:33 -07:00
|
|
|
return;
|
2011-07-10 19:29:16 -07:00
|
|
|
}
|
2011-08-18 23:58:33 -07:00
|
|
|
src->pub.bytes_in_buffer -= num_bytes;
|
|
|
|
src->pub.next_input_byte += num_bytes;
|
2011-06-07 06:34:18 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_evas_jpeg_membuf_src_term(j_decompress_ptr cinfo)
|
|
|
|
{
|
2011-07-29 18:13:29 -07:00
|
|
|
struct jpeg_membuf_src *src = (struct jpeg_membuf_src *)cinfo->src;
|
|
|
|
if (!src) return;
|
2011-06-07 06:34:18 -07:00
|
|
|
free(src);
|
|
|
|
cinfo->src = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
_evas_jpeg_membuf_src(j_decompress_ptr cinfo,
|
|
|
|
void *map, size_t length)
|
|
|
|
{
|
|
|
|
struct jpeg_membuf_src *src;
|
|
|
|
|
|
|
|
src = calloc(1, sizeof(*src));
|
|
|
|
if (!src)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
src->self = src;
|
|
|
|
|
|
|
|
cinfo->src = &src->pub;
|
|
|
|
src->buf = map;
|
|
|
|
src->len = length;
|
|
|
|
src->pub.init_source = _evas_jpeg_membuf_src_init;
|
|
|
|
src->pub.fill_input_buffer = _evas_jpeg_membuf_src_fill;
|
|
|
|
src->pub.skip_input_data = _evas_jpeg_membuf_src_skip;
|
|
|
|
src->pub.resync_to_restart = jpeg_resync_to_restart;
|
|
|
|
src->pub.term_source = _evas_jpeg_membuf_src_term;
|
|
|
|
src->pub.bytes_in_buffer = src->len;
|
|
|
|
src->pub.next_input_byte = src->buf;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2011-09-29 02:02:30 -07:00
|
|
|
/*! Magic number for EXIF header & App1*/
|
|
|
|
static const unsigned char ExifHeader[] = {0x45, 0x78, 0x69, 0x66, 0x00, 0x00};
|
|
|
|
static const unsigned char App1[] = {0xff, 0xe1};
|
|
|
|
typedef enum {
|
|
|
|
EXIF_BYTE_ALIGN_II,
|
|
|
|
EXIF_BYTE_ALIGN_MM
|
2011-09-30 08:54:26 -07:00
|
|
|
} ExifByteAlign;
|
2011-09-29 02:02:30 -07:00
|
|
|
|
|
|
|
static int
|
|
|
|
_get_orientation(void *map, size_t length)
|
|
|
|
{
|
|
|
|
char *buf;
|
2011-09-30 08:54:26 -07:00
|
|
|
char orientation[2];
|
2011-09-29 02:02:30 -07:00
|
|
|
ExifByteAlign byte_align;
|
2011-09-30 08:54:26 -07:00
|
|
|
unsigned int num_directory = 0;
|
|
|
|
unsigned int i, j;
|
2011-09-29 02:02:30 -07:00
|
|
|
int direction;
|
|
|
|
|
|
|
|
/* open file and get 22 byte frome file */
|
|
|
|
if (!map) return 0;
|
|
|
|
/* 1. read 22byte */
|
|
|
|
if (length < 22) return 0;
|
|
|
|
buf = (char *)map;
|
|
|
|
|
|
|
|
/* 2. check 2,3 bypte with APP1(0xFFE1) */
|
|
|
|
if (memcmp(buf + 2, App1, sizeof (App1))) return 0;
|
|
|
|
|
|
|
|
/* 3. check 6~11bype with Exif Header (0x45786966 0000) */
|
|
|
|
if (memcmp(buf + 6, ExifHeader, sizeof (ExifHeader))) return 0;
|
|
|
|
|
|
|
|
/* 4. get 12&13 byte get info of "II(0x4949)" or "MM(0x4d4d)" */
|
|
|
|
/* 5. get [20]&[21] get directory entry # */
|
|
|
|
if (!strncmp(buf + 12, "MM", 2))
|
|
|
|
{
|
|
|
|
byte_align = EXIF_BYTE_ALIGN_MM;
|
|
|
|
num_directory = ((*(buf + 20) << 8) + *(buf + 21));
|
|
|
|
orientation[0] = 0x01;
|
|
|
|
orientation[1] = 0x12;
|
|
|
|
}
|
|
|
|
else if (!strncmp(buf + 12, "II", 2))
|
|
|
|
{
|
|
|
|
byte_align = EXIF_BYTE_ALIGN_II;
|
|
|
|
num_directory = ((*(buf + 21) << 8) + *(buf + 20));
|
|
|
|
orientation[0] = 0x12;
|
|
|
|
orientation[1] = 0x01;
|
|
|
|
}
|
|
|
|
else return 0;
|
|
|
|
|
|
|
|
buf = map + 22;
|
|
|
|
|
|
|
|
if (length < (12 * num_directory + 22)) return 0;
|
|
|
|
|
|
|
|
j = 0;
|
|
|
|
|
|
|
|
for (i = 0; i < num_directory; i++ )
|
|
|
|
{
|
|
|
|
if (!strncmp(buf + j, orientation, 2))
|
|
|
|
{
|
|
|
|
/*get orientation tag */
|
|
|
|
if (byte_align == EXIF_BYTE_ALIGN_MM)
|
|
|
|
direction = *(buf+ j + 11);
|
|
|
|
else direction = *(buf+ j + 8);
|
|
|
|
switch (direction)
|
|
|
|
{
|
|
|
|
case 3:
|
|
|
|
case 4:
|
|
|
|
return 180;
|
|
|
|
case 6:
|
|
|
|
case 7:
|
|
|
|
return 90;
|
|
|
|
case 5:
|
|
|
|
case 8:
|
|
|
|
return 270;
|
|
|
|
default:
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
j = j + 12;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2009-12-22 15:11:57 -08:00
|
|
|
static Eina_Bool
|
2011-06-07 06:34:18 -07:00
|
|
|
evas_image_load_file_head_jpeg_internal(Image_Entry *ie,
|
|
|
|
void *map, size_t length,
|
|
|
|
int *error)
|
2006-01-14 12:03:42 -08:00
|
|
|
{
|
2010-09-18 16:16:25 -07:00
|
|
|
unsigned int w, h, scalew, scaleh;
|
2006-01-14 12:03:42 -08:00
|
|
|
struct jpeg_decompress_struct cinfo;
|
|
|
|
struct _JPEG_error_mgr jerr;
|
|
|
|
|
2011-09-29 02:02:30 -07:00
|
|
|
/* for rotation decoding */
|
|
|
|
int degree = 0;
|
|
|
|
Eina_Bool change_wh = EINA_FALSE;
|
2011-10-14 18:02:55 -07:00
|
|
|
unsigned int load_opts_w = 0, load_opts_h = 0;
|
2011-09-29 02:02:30 -07:00
|
|
|
|
2012-04-13 03:25:00 -07:00
|
|
|
memset(&cinfo, 0, sizeof(cinfo));
|
2006-01-14 12:03:42 -08:00
|
|
|
cinfo.err = jpeg_std_error(&(jerr.pub));
|
|
|
|
jerr.pub.error_exit = _JPEGFatalErrorHandler;
|
|
|
|
jerr.pub.emit_message = _JPEGErrorHandler2;
|
|
|
|
jerr.pub.output_message = _JPEGErrorHandler;
|
|
|
|
if (setjmp(jerr.setjmp_buffer))
|
|
|
|
{
|
|
|
|
jpeg_destroy_decompress(&cinfo);
|
2011-07-29 18:13:29 -07:00
|
|
|
_evas_jpeg_membuf_src_term(&cinfo);
|
2009-12-22 15:11:57 -08:00
|
|
|
if (cinfo.saw_JFIF_marker)
|
|
|
|
*error = EVAS_LOAD_ERROR_CORRUPT_FILE;
|
|
|
|
else
|
|
|
|
*error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
|
|
|
|
return EINA_FALSE;
|
2006-01-14 12:03:42 -08:00
|
|
|
}
|
2012-03-06 03:52:03 -08:00
|
|
|
jpeg_create_decompress(&cinfo);
|
2011-06-07 06:34:18 -07:00
|
|
|
|
|
|
|
if (_evas_jpeg_membuf_src(&cinfo, map, length))
|
|
|
|
{
|
|
|
|
jpeg_destroy_decompress(&cinfo);
|
2011-07-29 18:13:29 -07:00
|
|
|
_evas_jpeg_membuf_src_term(&cinfo);
|
2011-06-07 06:34:18 -07:00
|
|
|
*error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
|
2011-07-29 18:13:29 -07:00
|
|
|
return EINA_FALSE;
|
2011-06-07 06:34:18 -07:00
|
|
|
}
|
|
|
|
|
2006-01-14 12:03:42 -08:00
|
|
|
jpeg_read_header(&cinfo, TRUE);
|
|
|
|
cinfo.do_fancy_upsampling = FALSE;
|
|
|
|
cinfo.do_block_smoothing = FALSE;
|
2011-11-16 03:52:36 -08:00
|
|
|
cinfo.dct_method = JDCT_ISLOW; // JDCT_FLOAT JDCT_IFAST(quality loss)
|
2008-04-11 17:32:30 -07:00
|
|
|
cinfo.dither_mode = JDITHER_ORDERED;
|
2006-01-14 12:03:42 -08:00
|
|
|
jpeg_start_decompress(&cinfo);
|
|
|
|
|
2011-09-29 02:02:30 -07:00
|
|
|
/* rotation decoding */
|
|
|
|
if (ie->load_opts.orientation)
|
|
|
|
{
|
|
|
|
degree = _get_orientation(map, length);
|
|
|
|
if (degree != 0)
|
|
|
|
{
|
|
|
|
ie->load_opts.degree = degree;
|
|
|
|
ie->flags.rotated = EINA_TRUE;
|
|
|
|
|
|
|
|
if (degree == 90 || degree == 270)
|
|
|
|
change_wh = EINA_TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
/* head decoding */
|
2006-08-18 18:48:13 -07:00
|
|
|
w = cinfo.output_width;
|
|
|
|
h = cinfo.output_height;
|
2009-09-16 02:48:05 -07:00
|
|
|
if ((w < 1) || (h < 1) || (w > IMG_MAX_SIZE) || (h > IMG_MAX_SIZE) ||
|
|
|
|
(IMG_TOO_BIG(w, h)))
|
2009-05-05 14:48:50 -07:00
|
|
|
{
|
2006-11-04 21:07:53 -08:00
|
|
|
jpeg_destroy_decompress(&cinfo);
|
2011-07-29 18:13:29 -07:00
|
|
|
_evas_jpeg_membuf_src_term(&cinfo);
|
2009-12-22 15:11:57 -08:00
|
|
|
if (IMG_TOO_BIG(w, h))
|
|
|
|
*error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
|
|
|
|
else
|
|
|
|
*error = EVAS_LOAD_ERROR_GENERIC;
|
|
|
|
return EINA_FALSE;
|
2006-11-04 21:07:53 -08:00
|
|
|
}
|
2008-06-03 02:09:39 -07:00
|
|
|
if (ie->load_opts.scale_down_by > 1)
|
2006-08-18 18:48:13 -07:00
|
|
|
{
|
2008-06-03 02:09:39 -07:00
|
|
|
w /= ie->load_opts.scale_down_by;
|
|
|
|
h /= ie->load_opts.scale_down_by;
|
2006-08-18 18:48:13 -07:00
|
|
|
}
|
2008-06-03 02:09:39 -07:00
|
|
|
else if (ie->load_opts.dpi > 0.0)
|
2006-08-18 18:48:13 -07:00
|
|
|
{
|
2008-06-03 02:09:39 -07:00
|
|
|
w = (w * ie->load_opts.dpi) / 90.0;
|
|
|
|
h = (h * ie->load_opts.dpi) / 90.0;
|
2006-08-18 18:48:13 -07:00
|
|
|
}
|
2010-03-01 18:14:39 -08:00
|
|
|
else if ((ie->load_opts.w > 0) && (ie->load_opts.h > 0))
|
2006-08-18 18:48:13 -07:00
|
|
|
{
|
2011-09-29 02:02:30 -07:00
|
|
|
unsigned int w2 = w, h2 = h;
|
|
|
|
/* user set load_opts' w,h on the assumption
|
|
|
|
that image already rotated according to it's orientation info */
|
|
|
|
if (change_wh)
|
|
|
|
{
|
|
|
|
load_opts_w = ie->load_opts.w;
|
|
|
|
load_opts_h = ie->load_opts.h;
|
|
|
|
ie->load_opts.w = load_opts_h;
|
|
|
|
ie->load_opts.h = load_opts_w;
|
|
|
|
}
|
|
|
|
|
2009-01-29 08:45:14 -08:00
|
|
|
if (ie->load_opts.w > 0)
|
|
|
|
{
|
|
|
|
w2 = ie->load_opts.w;
|
|
|
|
h2 = (ie->load_opts.w * h) / w;
|
|
|
|
if ((ie->load_opts.h > 0) && (h2 > ie->load_opts.h))
|
|
|
|
{
|
2010-09-18 16:16:25 -07:00
|
|
|
unsigned int w3;
|
2009-01-29 08:45:14 -08:00
|
|
|
h2 = ie->load_opts.h;
|
2010-08-30 23:50:48 -07:00
|
|
|
w3 = (ie->load_opts.h * w) / h;
|
|
|
|
if (w3 > w2)
|
|
|
|
w2 = w3;
|
2009-01-29 08:45:14 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (ie->load_opts.h > 0)
|
2006-08-18 18:48:13 -07:00
|
|
|
{
|
2008-06-03 02:09:39 -07:00
|
|
|
h2 = ie->load_opts.h;
|
|
|
|
w2 = (ie->load_opts.h * w) / h;
|
2006-08-18 18:48:13 -07:00
|
|
|
}
|
|
|
|
w = w2;
|
|
|
|
h = h2;
|
2011-09-29 02:02:30 -07:00
|
|
|
if (change_wh)
|
|
|
|
{
|
|
|
|
ie->load_opts.w = load_opts_w;
|
|
|
|
ie->load_opts.h = load_opts_h;
|
|
|
|
}
|
2006-08-18 18:48:13 -07:00
|
|
|
}
|
|
|
|
if (w < 1) w = 1;
|
|
|
|
if (h < 1) h = 1;
|
2009-05-05 14:48:50 -07:00
|
|
|
|
2006-08-18 18:48:13 -07:00
|
|
|
if ((w != cinfo.output_width) || (h != cinfo.output_height))
|
|
|
|
{
|
|
|
|
scalew = cinfo.output_width / w;
|
|
|
|
scaleh = cinfo.output_height / h;
|
2009-05-05 14:48:50 -07:00
|
|
|
|
2008-06-03 02:09:39 -07:00
|
|
|
ie->scale = scalew;
|
|
|
|
if (scaleh < scalew) ie->scale = scaleh;
|
2009-05-05 14:48:50 -07:00
|
|
|
|
2008-06-03 02:09:39 -07:00
|
|
|
if (ie->scale > 8) ie->scale = 8;
|
|
|
|
else if (ie->scale < 1) ie->scale = 1;
|
2009-05-05 14:48:50 -07:00
|
|
|
|
2008-06-03 02:09:39 -07:00
|
|
|
if (ie->scale == 3) ie->scale = 2;
|
|
|
|
else if (ie->scale == 5) ie->scale = 4;
|
|
|
|
else if (ie->scale == 6) ie->scale = 4;
|
|
|
|
else if (ie->scale == 7) ie->scale = 4;
|
2006-08-18 18:48:13 -07:00
|
|
|
}
|
|
|
|
|
2008-06-03 02:09:39 -07:00
|
|
|
if (ie->scale > 1)
|
2006-08-18 18:48:13 -07:00
|
|
|
{
|
|
|
|
jpeg_destroy_decompress(&cinfo);
|
2011-07-29 18:13:29 -07:00
|
|
|
_evas_jpeg_membuf_src_term(&cinfo);
|
2006-08-18 18:48:13 -07:00
|
|
|
jpeg_create_decompress(&cinfo);
|
2011-06-07 06:34:18 -07:00
|
|
|
|
|
|
|
if (_evas_jpeg_membuf_src(&cinfo, map, length))
|
|
|
|
{
|
|
|
|
jpeg_destroy_decompress(&cinfo);
|
2011-07-29 18:13:29 -07:00
|
|
|
_evas_jpeg_membuf_src_term(&cinfo);
|
2011-06-07 06:34:18 -07:00
|
|
|
*error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
|
2011-07-29 18:13:29 -07:00
|
|
|
return EINA_FALSE;
|
2011-06-07 06:34:18 -07:00
|
|
|
}
|
|
|
|
|
2006-08-18 18:48:13 -07:00
|
|
|
jpeg_read_header(&cinfo, TRUE);
|
|
|
|
cinfo.do_fancy_upsampling = FALSE;
|
|
|
|
cinfo.do_block_smoothing = FALSE;
|
|
|
|
cinfo.scale_num = 1;
|
2008-06-03 02:09:39 -07:00
|
|
|
cinfo.scale_denom = ie->scale;
|
2006-08-18 18:48:13 -07:00
|
|
|
jpeg_calc_output_dimensions(&(cinfo));
|
|
|
|
jpeg_start_decompress(&cinfo);
|
|
|
|
}
|
2009-05-05 14:48:50 -07:00
|
|
|
|
2008-06-03 02:09:39 -07:00
|
|
|
ie->w = cinfo.output_width;
|
|
|
|
ie->h = cinfo.output_height;
|
2009-09-16 02:48:05 -07:00
|
|
|
|
|
|
|
// be nice and clip region to image. if its totally outside, fail load
|
|
|
|
if ((ie->load_opts.region.w > 0) && (ie->load_opts.region.h > 0))
|
|
|
|
{
|
2011-10-14 18:02:55 -07:00
|
|
|
unsigned int load_region_x = 0, load_region_y = 0;
|
|
|
|
unsigned int load_region_w = 0, load_region_h = 0;
|
2011-09-29 02:02:30 -07:00
|
|
|
if (ie->flags.rotated)
|
|
|
|
{
|
|
|
|
load_region_x = ie->load_opts.region.x;
|
|
|
|
load_region_y = ie->load_opts.region.y;
|
|
|
|
load_region_w = ie->load_opts.region.w;
|
|
|
|
load_region_h = ie->load_opts.region.h;
|
|
|
|
|
|
|
|
switch (degree)
|
|
|
|
{
|
|
|
|
case 90:
|
|
|
|
ie->load_opts.region.x = load_region_y;
|
|
|
|
ie->load_opts.region.y = h - (load_region_x + load_region_w);
|
|
|
|
ie->load_opts.region.w = load_region_h;
|
|
|
|
ie->load_opts.region.h = load_region_w;
|
|
|
|
break;
|
|
|
|
case 180:
|
|
|
|
ie->load_opts.region.x = w - (load_region_x+ load_region_w);
|
|
|
|
ie->load_opts.region.y = h - (load_region_y + load_region_h);
|
|
|
|
|
|
|
|
break;
|
|
|
|
case 270:
|
|
|
|
ie->load_opts.region.x = w - (load_region_y + load_region_h);
|
|
|
|
ie->load_opts.region.y = load_region_x;
|
|
|
|
ie->load_opts.region.w = load_region_h;
|
|
|
|
ie->load_opts.region.h = load_region_w;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
2009-09-16 02:48:05 -07:00
|
|
|
RECTS_CLIP_TO_RECT(ie->load_opts.region.x, ie->load_opts.region.y,
|
|
|
|
ie->load_opts.region.w, ie->load_opts.region.h,
|
|
|
|
0, 0, ie->w, ie->h);
|
|
|
|
if ((ie->load_opts.region.w <= 0) || (ie->load_opts.region.h <= 0))
|
|
|
|
{
|
|
|
|
jpeg_destroy_decompress(&cinfo);
|
2011-07-29 18:13:29 -07:00
|
|
|
_evas_jpeg_membuf_src_term(&cinfo);
|
2009-12-22 15:11:57 -08:00
|
|
|
*error = EVAS_LOAD_ERROR_GENERIC;
|
|
|
|
return EINA_FALSE;
|
2009-09-16 02:48:05 -07:00
|
|
|
}
|
|
|
|
ie->w = ie->load_opts.region.w;
|
|
|
|
ie->h = ie->load_opts.region.h;
|
2011-09-29 02:02:30 -07:00
|
|
|
if (ie->flags.rotated)
|
|
|
|
{
|
|
|
|
ie->load_opts.region.x = load_region_x;
|
|
|
|
ie->load_opts.region.y = load_region_y;
|
|
|
|
ie->load_opts.region.w = load_region_w;
|
|
|
|
ie->load_opts.region.h = load_region_h;
|
|
|
|
}
|
2009-09-16 02:48:05 -07:00
|
|
|
}
|
2006-01-14 12:03:42 -08:00
|
|
|
/* end head decoding */
|
|
|
|
|
2011-09-29 02:02:30 -07:00
|
|
|
if (change_wh)
|
|
|
|
{
|
|
|
|
unsigned int tmp;
|
|
|
|
tmp = ie->w;
|
|
|
|
ie->w = ie->h;
|
|
|
|
ie->h = tmp;
|
|
|
|
}
|
2006-01-14 12:03:42 -08:00
|
|
|
jpeg_destroy_decompress(&cinfo);
|
2011-07-29 18:13:29 -07:00
|
|
|
_evas_jpeg_membuf_src_term(&cinfo);
|
2009-12-22 15:11:57 -08:00
|
|
|
*error = EVAS_LOAD_ERROR_NONE;
|
|
|
|
return EINA_TRUE;
|
2006-01-14 12:03:42 -08:00
|
|
|
}
|
|
|
|
|
2009-10-22 15:33:06 -07:00
|
|
|
/*
|
2009-09-21 05:49:31 -07:00
|
|
|
static double
|
|
|
|
get_time(void)
|
|
|
|
{
|
|
|
|
struct timeval timev;
|
|
|
|
|
|
|
|
gettimeofday(&timev, NULL);
|
|
|
|
return (double)timev.tv_sec + (((double)timev.tv_usec) / 1000000);
|
|
|
|
}
|
2009-10-22 15:33:06 -07:00
|
|
|
*/
|
2009-09-21 05:49:31 -07:00
|
|
|
|
2009-12-22 15:11:57 -08:00
|
|
|
static Eina_Bool
|
2011-06-07 06:34:18 -07:00
|
|
|
evas_image_load_file_data_jpeg_internal(Image_Entry *ie,
|
|
|
|
void *map, size_t size,
|
|
|
|
int *error)
|
2006-01-14 12:03:42 -08:00
|
|
|
{
|
2010-09-18 16:16:25 -07:00
|
|
|
unsigned int w, h;
|
2006-01-14 12:03:42 -08:00
|
|
|
struct jpeg_decompress_struct cinfo;
|
|
|
|
struct _JPEG_error_mgr jerr;
|
|
|
|
DATA8 *ptr, *line[16], *data;
|
2011-10-25 05:20:53 -07:00
|
|
|
DATA32 *ptr2, *ptr_rotate = NULL;
|
2010-09-18 16:16:25 -07:00
|
|
|
unsigned int x, y, l, i, scans;
|
2009-09-16 02:48:05 -07:00
|
|
|
int region = 0;
|
2011-09-29 02:02:30 -07:00
|
|
|
/* rotation setting */
|
2012-03-06 03:52:03 -08:00
|
|
|
unsigned int ie_w = 0, ie_h = 0;
|
2011-10-14 18:02:55 -07:00
|
|
|
unsigned int load_region_x = 0, load_region_y = 0;
|
|
|
|
unsigned int load_region_w = 0, load_region_h = 0;
|
2012-02-18 00:56:00 -08:00
|
|
|
volatile int degree = 0;
|
|
|
|
volatile Eina_Bool change_wh = EINA_FALSE;
|
2011-09-29 02:02:30 -07:00
|
|
|
Eina_Bool line_done = EINA_FALSE;
|
|
|
|
|
2012-04-13 03:25:00 -07:00
|
|
|
memset(&cinfo, 0, sizeof(cinfo));
|
2011-09-29 02:02:30 -07:00
|
|
|
if (ie->flags.rotated)
|
|
|
|
{
|
|
|
|
degree = ie->load_opts.degree;
|
|
|
|
if (degree == 90 || degree == 270)
|
|
|
|
change_wh = EINA_TRUE;
|
|
|
|
}
|
|
|
|
|
2006-01-14 12:03:42 -08:00
|
|
|
cinfo.err = jpeg_std_error(&(jerr.pub));
|
|
|
|
jerr.pub.error_exit = _JPEGFatalErrorHandler;
|
|
|
|
jerr.pub.emit_message = _JPEGErrorHandler2;
|
|
|
|
jerr.pub.output_message = _JPEGErrorHandler;
|
|
|
|
if (setjmp(jerr.setjmp_buffer))
|
|
|
|
{
|
|
|
|
jpeg_destroy_decompress(&cinfo);
|
2011-07-29 18:13:29 -07:00
|
|
|
_evas_jpeg_membuf_src_term(&cinfo);
|
2009-12-22 15:11:57 -08:00
|
|
|
*error = EVAS_LOAD_ERROR_CORRUPT_FILE;
|
|
|
|
return EINA_FALSE;
|
2006-01-14 12:03:42 -08:00
|
|
|
}
|
|
|
|
jpeg_create_decompress(&cinfo);
|
2011-06-07 06:34:18 -07:00
|
|
|
|
|
|
|
if (_evas_jpeg_membuf_src(&cinfo, map, size))
|
|
|
|
{
|
|
|
|
jpeg_destroy_decompress(&cinfo);
|
2011-07-29 18:13:29 -07:00
|
|
|
_evas_jpeg_membuf_src_term(&cinfo);
|
2011-06-07 06:34:18 -07:00
|
|
|
*error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2006-01-14 12:03:42 -08:00
|
|
|
jpeg_read_header(&cinfo, TRUE);
|
|
|
|
cinfo.do_fancy_upsampling = FALSE;
|
|
|
|
cinfo.do_block_smoothing = FALSE;
|
2011-11-16 03:52:36 -08:00
|
|
|
cinfo.dct_method = JDCT_ISLOW; // JDCT_FLOAT JDCT_IFAST(quality loss)
|
2008-04-11 17:32:30 -07:00
|
|
|
cinfo.dither_mode = JDITHER_ORDERED;
|
|
|
|
|
2008-06-03 02:09:39 -07:00
|
|
|
if (ie->scale > 1)
|
2006-08-18 18:48:13 -07:00
|
|
|
{
|
|
|
|
cinfo.scale_num = 1;
|
2008-06-03 02:09:39 -07:00
|
|
|
cinfo.scale_denom = ie->scale;
|
2006-08-18 18:48:13 -07:00
|
|
|
}
|
2009-05-05 14:48:50 -07:00
|
|
|
|
|
|
|
/* Colorspace conversion options */
|
|
|
|
/* libjpeg can do the following conversions: */
|
|
|
|
/* GRAYSCLAE => RGB YCbCr => RGB and YCCK => CMYK */
|
|
|
|
switch (cinfo.jpeg_color_space)
|
|
|
|
{
|
|
|
|
case JCS_UNKNOWN:
|
|
|
|
break;
|
|
|
|
case JCS_GRAYSCALE:
|
|
|
|
case JCS_RGB:
|
|
|
|
case JCS_YCbCr:
|
|
|
|
cinfo.out_color_space = JCS_RGB;
|
|
|
|
break;
|
|
|
|
case JCS_CMYK:
|
|
|
|
case JCS_YCCK:
|
|
|
|
cinfo.out_color_space = JCS_CMYK;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2006-01-14 12:03:42 -08:00
|
|
|
/* head decoding */
|
2006-08-18 18:48:13 -07:00
|
|
|
jpeg_calc_output_dimensions(&(cinfo));
|
|
|
|
jpeg_start_decompress(&cinfo);
|
2009-05-05 14:48:50 -07:00
|
|
|
|
2006-08-18 18:48:13 -07:00
|
|
|
w = cinfo.output_width;
|
|
|
|
h = cinfo.output_height;
|
2009-05-05 14:48:50 -07:00
|
|
|
|
2011-09-29 02:02:30 -07:00
|
|
|
if (change_wh)
|
|
|
|
{
|
2012-03-06 03:52:03 -08:00
|
|
|
ie_w = ie->h;
|
|
|
|
ie_h = ie->w;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
ie_w = ie->w;
|
|
|
|
ie_h = ie->h;
|
2011-09-29 02:02:30 -07:00
|
|
|
}
|
|
|
|
|
2009-09-16 02:48:05 -07:00
|
|
|
if ((ie->load_opts.region.w > 0) && (ie->load_opts.region.h > 0))
|
2009-09-21 05:49:31 -07:00
|
|
|
{
|
|
|
|
region = 1;
|
2011-09-29 02:02:30 -07:00
|
|
|
|
|
|
|
if (ie->flags.rotated)
|
|
|
|
{
|
|
|
|
load_region_x = ie->load_opts.region.x;
|
|
|
|
load_region_y = ie->load_opts.region.y;
|
|
|
|
load_region_w = ie->load_opts.region.w;
|
|
|
|
load_region_h = ie->load_opts.region.h;
|
|
|
|
|
|
|
|
switch (degree)
|
|
|
|
{
|
|
|
|
case 90:
|
|
|
|
ie->load_opts.region.x = load_region_y;
|
|
|
|
ie->load_opts.region.y = h - (load_region_x + load_region_w);
|
|
|
|
ie->load_opts.region.w = load_region_h;
|
|
|
|
ie->load_opts.region.h = load_region_w;
|
|
|
|
break;
|
|
|
|
case 180:
|
|
|
|
ie->load_opts.region.x = w - (load_region_x+ load_region_w);
|
|
|
|
ie->load_opts.region.y = h - (load_region_y + load_region_h);
|
|
|
|
|
|
|
|
break;
|
|
|
|
case 270:
|
|
|
|
ie->load_opts.region.x = w - (load_region_y + load_region_h);
|
|
|
|
ie->load_opts.region.y = load_region_x;
|
|
|
|
ie->load_opts.region.w = load_region_h;
|
|
|
|
ie->load_opts.region.h = load_region_w;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
2009-09-21 05:49:31 -07:00
|
|
|
#ifdef BUILD_LOADER_JPEG_REGION
|
|
|
|
cinfo.region_x = ie->load_opts.region.x;
|
|
|
|
cinfo.region_y = ie->load_opts.region.y;
|
|
|
|
cinfo.region_w = ie->load_opts.region.w;
|
|
|
|
cinfo.region_h = ie->load_opts.region.h;
|
|
|
|
#endif
|
|
|
|
}
|
2012-03-06 03:52:03 -08:00
|
|
|
if ((!region) && ((w != ie_w) || (h != ie_h)))
|
2006-08-18 18:49:33 -07:00
|
|
|
{
|
2012-03-06 03:52:03 -08:00
|
|
|
// race condition, the file could have change from when we call header
|
|
|
|
// this test will not solve the problem with region code.
|
|
|
|
jpeg_destroy_decompress(&cinfo);
|
2011-07-29 18:13:29 -07:00
|
|
|
_evas_jpeg_membuf_src_term(&cinfo);
|
2012-03-06 03:52:03 -08:00
|
|
|
*error = EVAS_LOAD_ERROR_GENERIC;
|
|
|
|
return EINA_FALSE;
|
2009-09-16 02:48:05 -07:00
|
|
|
}
|
2010-04-21 06:47:42 -07:00
|
|
|
if ((region) &&
|
2012-03-06 03:52:03 -08:00
|
|
|
((ie_w != ie->load_opts.region.w) || (ie_h != ie->load_opts.region.h)))
|
2009-09-16 02:48:05 -07:00
|
|
|
{
|
2012-03-06 03:52:03 -08:00
|
|
|
ie_w = ie->load_opts.region.w;
|
|
|
|
ie_h = ie->load_opts.region.h;
|
|
|
|
if (change_wh)
|
|
|
|
{
|
|
|
|
ie->w = ie_h;
|
|
|
|
ie->h = ie_w;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
ie->w = ie_w;
|
|
|
|
ie->h = ie_h;
|
|
|
|
}
|
|
|
|
|
2006-08-18 18:49:33 -07:00
|
|
|
}
|
2009-05-05 14:48:50 -07:00
|
|
|
|
|
|
|
if (!(((cinfo.out_color_space == JCS_RGB) &&
|
|
|
|
((cinfo.output_components == 3) || (cinfo.output_components == 1))) ||
|
2009-06-16 06:01:36 -07:00
|
|
|
((cinfo.out_color_space == JCS_CMYK) && (cinfo.output_components == 4))))
|
2009-05-05 14:48:50 -07:00
|
|
|
{
|
|
|
|
jpeg_destroy_decompress(&cinfo);
|
2011-07-29 18:13:29 -07:00
|
|
|
_evas_jpeg_membuf_src_term(&cinfo);
|
2009-12-22 15:11:57 -08:00
|
|
|
*error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
|
|
|
|
return EINA_FALSE;
|
2009-05-05 14:48:50 -07:00
|
|
|
}
|
|
|
|
|
2006-01-14 12:03:42 -08:00
|
|
|
/* end head decoding */
|
|
|
|
/* data decoding */
|
|
|
|
if (cinfo.rec_outbuf_height > 16)
|
|
|
|
{
|
|
|
|
jpeg_destroy_decompress(&cinfo);
|
2011-07-29 18:13:29 -07:00
|
|
|
_evas_jpeg_membuf_src_term(&cinfo);
|
2009-12-22 15:11:57 -08:00
|
|
|
*error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
|
|
|
|
return EINA_FALSE;
|
2006-01-14 12:03:42 -08:00
|
|
|
}
|
2009-05-05 14:48:50 -07:00
|
|
|
data = alloca(w * 16 * cinfo.output_components);
|
2009-09-16 02:48:05 -07:00
|
|
|
evas_cache_image_surface_alloc(ie, ie->w, ie->h);
|
2008-06-03 02:09:39 -07:00
|
|
|
if (ie->flags.loaded)
|
2006-01-14 12:03:42 -08:00
|
|
|
{
|
|
|
|
jpeg_destroy_decompress(&cinfo);
|
2011-07-29 18:13:29 -07:00
|
|
|
_evas_jpeg_membuf_src_term(&cinfo);
|
2009-12-22 15:11:57 -08:00
|
|
|
*error = EVAS_LOAD_ERROR_NONE;
|
2011-09-29 02:02:30 -07:00
|
|
|
if (region && ie->flags.rotated)
|
|
|
|
{
|
|
|
|
ie->load_opts.region.x = load_region_x;
|
|
|
|
ie->load_opts.region.y = load_region_y;
|
|
|
|
ie->load_opts.region.w = load_region_w;
|
|
|
|
ie->load_opts.region.h = load_region_h;
|
|
|
|
}
|
2009-12-22 15:11:57 -08:00
|
|
|
return EINA_TRUE;
|
2006-01-14 12:03:42 -08:00
|
|
|
}
|
2011-09-29 02:02:30 -07:00
|
|
|
if ((ie->flags.rotated) && change_wh)
|
|
|
|
{
|
|
|
|
ptr2 = malloc(ie->w * ie->h * sizeof(DATA32));
|
|
|
|
ptr_rotate = ptr2;
|
|
|
|
}
|
|
|
|
else
|
2011-10-25 05:20:53 -07:00
|
|
|
ptr2 = evas_cache_image_pixels(ie);
|
2011-09-29 02:02:30 -07:00
|
|
|
|
2011-05-19 02:22:35 -07:00
|
|
|
if (!ptr2)
|
|
|
|
{
|
|
|
|
*error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
|
|
|
|
return EINA_FALSE;
|
|
|
|
}
|
2010-07-31 09:57:09 -07:00
|
|
|
|
2009-05-05 14:48:50 -07:00
|
|
|
/* We handle first CMYK (4 components) */
|
|
|
|
if (cinfo.output_components == 4)
|
|
|
|
{
|
2009-09-16 02:48:05 -07:00
|
|
|
// FIXME: handle region
|
2010-09-18 16:16:25 -07:00
|
|
|
for (i = 0; (int)i < cinfo.rec_outbuf_height; i++)
|
2009-05-05 14:48:50 -07:00
|
|
|
line[i] = data + (i * w * 4);
|
|
|
|
for (l = 0; l < h; l += cinfo.rec_outbuf_height)
|
|
|
|
{
|
|
|
|
jpeg_read_scanlines(&cinfo, line, cinfo.rec_outbuf_height);
|
|
|
|
scans = cinfo.rec_outbuf_height;
|
|
|
|
if ((h - l) < scans) scans = h - l;
|
|
|
|
ptr = data;
|
2009-09-20 07:31:48 -07:00
|
|
|
if (!region)
|
|
|
|
{
|
|
|
|
for (y = 0; y < scans; y++)
|
|
|
|
{
|
2009-05-05 14:48:50 -07:00
|
|
|
if (cinfo.saw_Adobe_marker)
|
2009-09-20 07:31:48 -07:00
|
|
|
{
|
|
|
|
for (x = 0; x < w; x++)
|
|
|
|
{
|
|
|
|
/* According to libjpeg doc, Photoshop inverse the values of C, M, Y and K, */
|
|
|
|
/* that is C is replaces by 255 - C, etc...*/
|
|
|
|
/* See the comment below for the computation of RGB values from CMYK ones. */
|
|
|
|
*ptr2 =
|
|
|
|
(0xff000000) |
|
|
|
|
((ptr[0] * ptr[3] / 255) << 16) |
|
|
|
|
((ptr[1] * ptr[3] / 255) << 8) |
|
|
|
|
((ptr[2] * ptr[3] / 255));
|
|
|
|
ptr += 4;
|
|
|
|
ptr2++;
|
|
|
|
}
|
|
|
|
}
|
2009-05-05 14:48:50 -07:00
|
|
|
else
|
2009-09-20 07:31:48 -07:00
|
|
|
{
|
|
|
|
for (x = 0; x < w; x++)
|
|
|
|
{
|
|
|
|
/* Conversion from CMYK to RGB is done in 2 steps: */
|
|
|
|
/* CMYK => CMY => RGB (see http://www.easyrgb.com/index.php?X=MATH) */
|
|
|
|
/* after computation, if C, M, Y and K are between 0 and 1, we have: */
|
|
|
|
/* R = (1 - C) * (1 - K) * 255 */
|
|
|
|
/* G = (1 - M) * (1 - K) * 255 */
|
|
|
|
/* B = (1 - Y) * (1 - K) * 255 */
|
|
|
|
/* libjpeg stores CMYK values between 0 and 255, */
|
|
|
|
/* so we replace C by C * 255 / 255, etc... and we obtain: */
|
|
|
|
/* R = (255 - C) * (255 - K) / 255 */
|
|
|
|
/* G = (255 - M) * (255 - K) / 255 */
|
|
|
|
/* B = (255 - Y) * (255 - K) / 255 */
|
|
|
|
/* with C, M, Y and K between 0 and 255. */
|
|
|
|
*ptr2 =
|
|
|
|
(0xff000000) |
|
|
|
|
(((255 - ptr[0]) * (255 - ptr[3]) / 255) << 16) |
|
|
|
|
(((255 - ptr[1]) * (255 - ptr[3]) / 255) << 8) |
|
|
|
|
(((255 - ptr[2]) * (255 - ptr[3]) / 255));
|
|
|
|
ptr += 4;
|
|
|
|
ptr2++;
|
|
|
|
}
|
|
|
|
}
|
2009-05-05 14:48:50 -07:00
|
|
|
}
|
|
|
|
}
|
2009-09-20 07:31:48 -07:00
|
|
|
else
|
|
|
|
{
|
|
|
|
// if line # > region last line, break
|
|
|
|
if (l >= (ie->load_opts.region.y + ie->load_opts.region.h))
|
|
|
|
{
|
2011-09-29 02:02:30 -07:00
|
|
|
line_done = EINA_TRUE;
|
|
|
|
/* if rotation flag is set , we have to rotate image */
|
|
|
|
goto done;
|
|
|
|
/*jpeg_destroy_decompress(&cinfo);
|
|
|
|
_evas_jpeg_membuf_src_term(&cinfo);
|
|
|
|
*error = EVAS_LOAD_ERROR_NONE;
|
|
|
|
return EINA_FALSE;*/
|
2009-09-20 07:31:48 -07:00
|
|
|
}
|
|
|
|
// els if scan block intersects region start or later
|
|
|
|
else if ((l + scans) >
|
|
|
|
(ie->load_opts.region.y))
|
|
|
|
{
|
|
|
|
for (y = 0; y < scans; y++)
|
|
|
|
{
|
|
|
|
if (((y + l) >= ie->load_opts.region.y) &&
|
|
|
|
((y + l) < (ie->load_opts.region.y + ie->load_opts.region.h)))
|
|
|
|
{
|
|
|
|
ptr += ie->load_opts.region.x;
|
|
|
|
if (cinfo.saw_Adobe_marker)
|
|
|
|
{
|
|
|
|
for (x = 0; x < ie->load_opts.region.w; x++)
|
|
|
|
{
|
|
|
|
/* According to libjpeg doc, Photoshop inverse the values of C, M, Y and K, */
|
|
|
|
/* that is C is replaces by 255 - C, etc...*/
|
|
|
|
/* See the comment below for the computation of RGB values from CMYK ones. */
|
|
|
|
*ptr2 =
|
|
|
|
(0xff000000) |
|
|
|
|
((ptr[0] * ptr[3] / 255) << 16) |
|
|
|
|
((ptr[1] * ptr[3] / 255) << 8) |
|
|
|
|
((ptr[2] * ptr[3] / 255));
|
|
|
|
ptr += 4;
|
|
|
|
ptr2++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
for (x = 0; x < ie->load_opts.region.w; x++)
|
|
|
|
{
|
|
|
|
/* Conversion from CMYK to RGB is done in 2 steps: */
|
|
|
|
/* CMYK => CMY => RGB (see http://www.easyrgb.com/index.php?X=MATH) */
|
|
|
|
/* after computation, if C, M, Y and K are between 0 and 1, we have: */
|
|
|
|
/* R = (1 - C) * (1 - K) * 255 */
|
|
|
|
/* G = (1 - M) * (1 - K) * 255 */
|
|
|
|
/* B = (1 - Y) * (1 - K) * 255 */
|
|
|
|
/* libjpeg stores CMYK values between 0 and 255, */
|
|
|
|
/* so we replace C by C * 255 / 255, etc... and we obtain: */
|
|
|
|
/* R = (255 - C) * (255 - K) / 255 */
|
|
|
|
/* G = (255 - M) * (255 - K) / 255 */
|
|
|
|
/* B = (255 - Y) * (255 - K) / 255 */
|
|
|
|
/* with C, M, Y and K between 0 and 255. */
|
|
|
|
*ptr2 =
|
|
|
|
(0xff000000) |
|
|
|
|
(((255 - ptr[0]) * (255 - ptr[3]) / 255) << 16) |
|
|
|
|
(((255 - ptr[1]) * (255 - ptr[3]) / 255) << 8) |
|
|
|
|
(((255 - ptr[2]) * (255 - ptr[3]) / 255));
|
|
|
|
ptr += 4;
|
|
|
|
ptr2++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
ptr += (4 * (w - (ie->load_opts.region.x + ie->load_opts.region.w)));
|
|
|
|
}
|
|
|
|
else
|
|
|
|
ptr += (4 * w);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2009-05-05 14:48:50 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
/* We handle then RGB with 3 components */
|
|
|
|
else if (cinfo.output_components == 3)
|
2006-01-14 12:03:42 -08:00
|
|
|
{
|
2009-09-21 05:49:31 -07:00
|
|
|
/*
|
|
|
|
double t;
|
2009-09-16 02:48:05 -07:00
|
|
|
if (region)
|
|
|
|
{
|
2009-09-20 07:31:48 -07:00
|
|
|
// debug for now
|
2009-09-21 05:49:31 -07:00
|
|
|
printf("R| %p %5ix%5i %s: %5i %5i %5ix%5i - ",
|
2009-09-20 07:31:48 -07:00
|
|
|
ie,
|
2009-09-16 02:48:05 -07:00
|
|
|
ie->w, ie->h,
|
|
|
|
ie->file,
|
|
|
|
ie->load_opts.region.x,
|
|
|
|
ie->load_opts.region.y,
|
|
|
|
ie->load_opts.region.w,
|
|
|
|
ie->load_opts.region.h);
|
|
|
|
}
|
2009-09-21 05:49:31 -07:00
|
|
|
t = get_time();
|
|
|
|
*/
|
2010-09-18 16:16:25 -07:00
|
|
|
for (i = 0; (int)i < cinfo.rec_outbuf_height; i++)
|
2006-01-14 12:03:42 -08:00
|
|
|
line[i] = data + (i * w * 3);
|
|
|
|
for (l = 0; l < h; l += cinfo.rec_outbuf_height)
|
|
|
|
{
|
|
|
|
jpeg_read_scanlines(&cinfo, line, cinfo.rec_outbuf_height);
|
|
|
|
scans = cinfo.rec_outbuf_height;
|
|
|
|
if ((h - l) < scans) scans = h - l;
|
|
|
|
ptr = data;
|
2009-09-16 02:48:05 -07:00
|
|
|
if (!region)
|
|
|
|
{
|
|
|
|
for (y = 0; y < scans; y++)
|
|
|
|
{
|
|
|
|
for (x = 0; x < w; x++)
|
|
|
|
{
|
2010-06-07 22:39:46 -07:00
|
|
|
*ptr2 = ARGB_JOIN(0xff, ptr[0], ptr[1], ptr[2]);
|
2009-09-16 02:48:05 -07:00
|
|
|
ptr += 3;
|
|
|
|
ptr2++;
|
|
|
|
}
|
|
|
|
}
|
2006-01-14 12:03:42 -08:00
|
|
|
}
|
2009-09-16 02:48:05 -07:00
|
|
|
else
|
|
|
|
{
|
|
|
|
// if line # > region last line, break
|
2011-09-29 02:02:30 -07:00
|
|
|
// but not return immediately for rotation job
|
2009-09-16 02:48:05 -07:00
|
|
|
if (l >= (ie->load_opts.region.y + ie->load_opts.region.h))
|
|
|
|
{
|
2011-09-29 02:02:30 -07:00
|
|
|
line_done = EINA_TRUE;
|
|
|
|
/* if rotation flag is set , we have to rotate image */
|
|
|
|
goto done;
|
2009-09-16 02:48:05 -07:00
|
|
|
}
|
2009-09-21 05:49:31 -07:00
|
|
|
// else if scan block intersects region start or later
|
2009-09-16 02:48:05 -07:00
|
|
|
else if ((l + scans) >
|
|
|
|
(ie->load_opts.region.y))
|
|
|
|
{
|
|
|
|
for (y = 0; y < scans; y++)
|
|
|
|
{
|
|
|
|
if (((y + l) >= ie->load_opts.region.y) &&
|
|
|
|
((y + l) < (ie->load_opts.region.y + ie->load_opts.region.h)))
|
|
|
|
{
|
|
|
|
ptr += (3 * ie->load_opts.region.x);
|
|
|
|
for (x = 0; x < ie->load_opts.region.w; x++)
|
|
|
|
{
|
2010-06-07 22:39:46 -07:00
|
|
|
*ptr2 = ARGB_JOIN(0xff, ptr[0], ptr[1], ptr[2]);
|
2009-09-16 02:48:05 -07:00
|
|
|
ptr += 3;
|
|
|
|
ptr2++;
|
|
|
|
}
|
|
|
|
ptr += (3 * (w - (ie->load_opts.region.x + ie->load_opts.region.w)));
|
|
|
|
}
|
|
|
|
else
|
|
|
|
ptr += (3 * w);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2006-01-14 12:03:42 -08:00
|
|
|
}
|
2009-09-21 05:49:31 -07:00
|
|
|
/*
|
|
|
|
t = get_time() - t;
|
|
|
|
printf("%3.3f\n", t);
|
|
|
|
*/
|
2006-01-14 12:03:42 -08:00
|
|
|
}
|
2009-05-05 14:48:50 -07:00
|
|
|
/* We finally handle RGB with 1 component */
|
2006-01-14 12:03:42 -08:00
|
|
|
else if (cinfo.output_components == 1)
|
|
|
|
{
|
2010-09-18 16:16:25 -07:00
|
|
|
for (i = 0; (int)i < cinfo.rec_outbuf_height; i++)
|
2006-01-14 12:03:42 -08:00
|
|
|
line[i] = data + (i * w);
|
|
|
|
for (l = 0; l < h; l += cinfo.rec_outbuf_height)
|
|
|
|
{
|
|
|
|
jpeg_read_scanlines(&cinfo, line, cinfo.rec_outbuf_height);
|
|
|
|
scans = cinfo.rec_outbuf_height;
|
|
|
|
if ((h - l) < scans) scans = h - l;
|
|
|
|
ptr = data;
|
2009-09-20 07:31:48 -07:00
|
|
|
if (!region)
|
|
|
|
{
|
|
|
|
for (y = 0; y < scans; y++)
|
|
|
|
{
|
|
|
|
for (x = 0; x < w; x++)
|
|
|
|
{
|
2010-06-07 22:39:46 -07:00
|
|
|
*ptr2 = ARGB_JOIN(0xff, ptr[0], ptr[0], ptr[0]);
|
2009-09-20 07:31:48 -07:00
|
|
|
ptr++;
|
|
|
|
ptr2++;
|
|
|
|
}
|
|
|
|
}
|
2006-01-14 12:03:42 -08:00
|
|
|
}
|
2009-09-20 07:31:48 -07:00
|
|
|
else
|
|
|
|
{
|
|
|
|
// if line # > region last line, break
|
|
|
|
if (l >= (ie->load_opts.region.y + ie->load_opts.region.h))
|
|
|
|
{
|
2011-09-29 02:02:30 -07:00
|
|
|
line_done = EINA_TRUE;
|
|
|
|
/* if rotation flag is set , we have to rotate image */
|
|
|
|
goto done;
|
|
|
|
/*jpeg_destroy_decompress(&cinfo);
|
|
|
|
_evas_jpeg_membuf_src_term(&cinfo);
|
|
|
|
*error = EVAS_LOAD_ERROR_NONE;
|
|
|
|
return EINA_TRUE;*/
|
2009-09-20 07:31:48 -07:00
|
|
|
}
|
|
|
|
// els if scan block intersects region start or later
|
|
|
|
else if ((l + scans) >
|
|
|
|
(ie->load_opts.region.y))
|
|
|
|
{
|
|
|
|
for (y = 0; y < scans; y++)
|
|
|
|
{
|
|
|
|
if (((y + l) >= ie->load_opts.region.y) &&
|
|
|
|
((y + l) < (ie->load_opts.region.y + ie->load_opts.region.h)))
|
|
|
|
{
|
|
|
|
ptr += ie->load_opts.region.x;
|
|
|
|
for (x = 0; x < ie->load_opts.region.w; x++)
|
|
|
|
{
|
2010-06-07 22:39:46 -07:00
|
|
|
*ptr2 = ARGB_JOIN(0xff, ptr[0], ptr[0], ptr[0]);
|
2009-09-20 07:31:48 -07:00
|
|
|
ptr++;
|
|
|
|
ptr2++;
|
|
|
|
}
|
|
|
|
ptr += w - (ie->load_opts.region.x + ie->load_opts.region.w);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
ptr += w;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2006-01-14 12:03:42 -08:00
|
|
|
}
|
|
|
|
}
|
2011-09-29 02:02:30 -07:00
|
|
|
/* if rotation operation need, rotate it */
|
|
|
|
done:
|
|
|
|
|
|
|
|
if (ie->flags.rotated)
|
|
|
|
{
|
|
|
|
DATA32 *data1, *data2, *to, *from;
|
2012-02-09 02:21:17 -08:00
|
|
|
int lx, ly, lw, lh, hw;
|
2011-09-29 02:02:30 -07:00
|
|
|
|
2012-02-09 02:21:17 -08:00
|
|
|
lw = ie->w;
|
|
|
|
lh = ie->h;
|
|
|
|
hw =lw * lh;
|
2011-09-29 02:02:30 -07:00
|
|
|
|
|
|
|
data1 = evas_cache_image_pixels(ie);
|
|
|
|
|
|
|
|
if (degree == 180)
|
|
|
|
{
|
2012-02-09 02:21:17 -08:00
|
|
|
DATA32 tmpd;
|
2011-09-29 02:02:30 -07:00
|
|
|
|
2012-02-09 02:21:17 -08:00
|
|
|
data2 = data1 + (lh * lw) -1;
|
|
|
|
for (lx = (lw * lh) / 2; --lx >= 0;)
|
2011-09-29 02:02:30 -07:00
|
|
|
{
|
2012-02-09 02:21:17 -08:00
|
|
|
tmpd = *data1;
|
2011-09-29 02:02:30 -07:00
|
|
|
*data1 = *data2;
|
2012-02-09 02:21:17 -08:00
|
|
|
*data2 = tmpd;
|
2011-09-29 02:02:30 -07:00
|
|
|
data1++;
|
|
|
|
data2--;
|
|
|
|
}
|
|
|
|
}
|
2011-10-25 05:20:53 -07:00
|
|
|
else
|
2011-09-29 02:02:30 -07:00
|
|
|
{
|
2011-10-25 05:20:53 -07:00
|
|
|
data2 = NULL;
|
|
|
|
to = NULL;
|
|
|
|
if (ptr_rotate) data2 = ptr_rotate;
|
2011-09-29 02:02:30 -07:00
|
|
|
|
|
|
|
if (degree == 90)
|
|
|
|
{
|
2012-02-09 02:21:17 -08:00
|
|
|
to = data1 + lw - 1;
|
2011-09-29 02:02:30 -07:00
|
|
|
hw = -hw - 1;
|
|
|
|
}
|
|
|
|
else if (degree == 270)
|
|
|
|
{
|
2012-02-09 02:21:17 -08:00
|
|
|
to = data1 + hw - lw;
|
|
|
|
lw = -lw;
|
2011-09-29 02:02:30 -07:00
|
|
|
hw = hw + 1;
|
|
|
|
}
|
|
|
|
|
2011-10-25 05:20:53 -07:00
|
|
|
if (to)
|
2011-09-29 02:02:30 -07:00
|
|
|
{
|
2011-10-25 05:20:53 -07:00
|
|
|
from = data2;
|
2012-02-09 02:21:17 -08:00
|
|
|
for (lx = ie->w; --lx >= 0;)
|
2011-09-29 02:02:30 -07:00
|
|
|
{
|
2012-02-09 02:21:17 -08:00
|
|
|
for (ly =ie->h; --ly >= 0;)
|
2011-10-25 05:20:53 -07:00
|
|
|
{
|
|
|
|
*to = *from;
|
|
|
|
from++;
|
2012-02-09 02:21:17 -08:00
|
|
|
to += lw;
|
2011-10-25 05:20:53 -07:00
|
|
|
}
|
|
|
|
to += hw;
|
2011-09-29 02:02:30 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
if (ptr_rotate)
|
|
|
|
{
|
|
|
|
free(ptr_rotate);
|
|
|
|
ptr_rotate = NULL;
|
|
|
|
}
|
|
|
|
}
|
2011-10-25 05:20:53 -07:00
|
|
|
if (region)
|
2011-09-29 02:02:30 -07:00
|
|
|
{
|
|
|
|
ie->load_opts.region.x = load_region_x;
|
|
|
|
ie->load_opts.region.y = load_region_y;
|
|
|
|
ie->load_opts.region.w = load_region_w;
|
|
|
|
ie->load_opts.region.h = load_region_h;
|
|
|
|
}
|
|
|
|
}
|
2012-03-06 03:52:03 -08:00
|
|
|
|
2011-09-29 02:02:30 -07:00
|
|
|
if (line_done)
|
|
|
|
{
|
|
|
|
jpeg_destroy_decompress(&cinfo);
|
|
|
|
_evas_jpeg_membuf_src_term(&cinfo);
|
|
|
|
*error = EVAS_LOAD_ERROR_NONE;
|
|
|
|
return EINA_FALSE;
|
|
|
|
}
|
|
|
|
/* end data decoding */
|
2006-01-14 12:03:42 -08:00
|
|
|
jpeg_finish_decompress(&cinfo);
|
|
|
|
jpeg_destroy_decompress(&cinfo);
|
2011-07-29 18:13:29 -07:00
|
|
|
_evas_jpeg_membuf_src_term(&cinfo);
|
2009-12-22 15:11:57 -08:00
|
|
|
*error = EVAS_LOAD_ERROR_NONE;
|
|
|
|
return EINA_TRUE;
|
2006-01-14 12:03:42 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
#if 0 /* not used at the moment */
|
2009-12-22 15:11:57 -08:00
|
|
|
static Eina_Bool
|
|
|
|
evas_image_load_file_data_jpeg_alpha_internal(Image_Entry *ie, FILE *f, int *error)
|
2006-01-14 12:03:42 -08:00
|
|
|
{
|
|
|
|
int w, h;
|
|
|
|
struct jpeg_decompress_struct cinfo;
|
|
|
|
struct _JPEG_error_mgr jerr;
|
|
|
|
DATA8 *ptr, *line[16], *data;
|
|
|
|
DATA32 *ptr2;
|
2010-07-31 09:57:09 -07:00
|
|
|
int x, y, l, i, scans, prevy;
|
2006-01-14 12:03:42 -08:00
|
|
|
|
2009-12-22 15:11:57 -08:00
|
|
|
if (!f)
|
|
|
|
{
|
|
|
|
*error = EVAS_LOAD_ERROR_DOES_NOT_EXIST;
|
|
|
|
return EINA_FALSE;
|
|
|
|
}
|
2006-01-14 12:03:42 -08:00
|
|
|
cinfo.err = jpeg_std_error(&(jerr.pub));
|
|
|
|
jerr.pub.error_exit = _JPEGFatalErrorHandler;
|
|
|
|
jerr.pub.emit_message = _JPEGErrorHandler2;
|
|
|
|
jerr.pub.output_message = _JPEGErrorHandler;
|
|
|
|
if (setjmp(jerr.setjmp_buffer))
|
|
|
|
{
|
|
|
|
jpeg_destroy_decompress(&cinfo);
|
2009-12-22 15:11:57 -08:00
|
|
|
*error = EVAS_LOAD_ERROR_CORRUPT_FILE;
|
|
|
|
return EINA_FALSE;
|
2006-01-14 12:03:42 -08:00
|
|
|
}
|
|
|
|
jpeg_create_decompress(&cinfo);
|
|
|
|
jpeg_stdio_src(&cinfo, f);
|
|
|
|
jpeg_read_header(&cinfo, TRUE);
|
|
|
|
cinfo.do_fancy_upsampling = FALSE;
|
|
|
|
cinfo.do_block_smoothing = FALSE;
|
|
|
|
jpeg_start_decompress(&cinfo);
|
|
|
|
|
|
|
|
/* head decoding */
|
2008-06-03 02:09:39 -07:00
|
|
|
ie->w = w = cinfo.output_width;
|
|
|
|
ie->h = h = cinfo.output_height;
|
2006-01-14 12:03:42 -08:00
|
|
|
/* end head decoding */
|
|
|
|
/* data decoding */
|
|
|
|
if (cinfo.rec_outbuf_height > 16)
|
|
|
|
{
|
|
|
|
jpeg_destroy_decompress(&cinfo);
|
2009-12-22 15:11:57 -08:00
|
|
|
*error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
|
|
|
|
return EINA_FALSE;;
|
2006-01-14 12:03:42 -08:00
|
|
|
}
|
|
|
|
data = alloca(w * 16 * 3);
|
2008-06-03 02:09:39 -07:00
|
|
|
if (!ie->flags.loaded)
|
2006-01-14 12:03:42 -08:00
|
|
|
{
|
|
|
|
jpeg_destroy_decompress(&cinfo);
|
2009-12-22 15:11:57 -08:00
|
|
|
*error = EVAS_LOAD_ERROR_NONE;
|
|
|
|
return EINA_TRUE;
|
2006-01-14 12:03:42 -08:00
|
|
|
}
|
2008-06-03 02:09:39 -07:00
|
|
|
ptr2 = evas_cache_image_pixels(ie);
|
2006-01-14 12:03:42 -08:00
|
|
|
prevy = 0;
|
|
|
|
if (cinfo.output_components == 3)
|
|
|
|
{
|
|
|
|
for (i = 0; i < cinfo.rec_outbuf_height; i++)
|
|
|
|
line[i] = data + (i * w * 3);
|
|
|
|
for (l = 0; l < h; l += cinfo.rec_outbuf_height)
|
|
|
|
{
|
|
|
|
jpeg_read_scanlines(&cinfo, line, cinfo.rec_outbuf_height);
|
|
|
|
scans = cinfo.rec_outbuf_height;
|
|
|
|
if ((h - l) < scans) scans = h - l;
|
|
|
|
ptr = data;
|
|
|
|
for (y = 0; y < scans; y++)
|
|
|
|
{
|
|
|
|
for (x = 0; x < w; x++)
|
|
|
|
{
|
|
|
|
*ptr2 =
|
|
|
|
((*ptr2) & 0x00ffffff) |
|
|
|
|
(((ptr[0] + ptr[1] + ptr[2]) / 3) << 24);
|
|
|
|
ptr += 3;
|
|
|
|
ptr2++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (cinfo.output_components == 1)
|
|
|
|
{
|
|
|
|
for (i = 0; i < cinfo.rec_outbuf_height; i++)
|
|
|
|
line[i] = data + (i * w);
|
|
|
|
for (l = 0; l < h; l += cinfo.rec_outbuf_height)
|
|
|
|
{
|
|
|
|
jpeg_read_scanlines(&cinfo, line, cinfo.rec_outbuf_height);
|
|
|
|
scans = cinfo.rec_outbuf_height;
|
|
|
|
if ((h - l) < scans) scans = h - l;
|
|
|
|
ptr = data;
|
|
|
|
for (y = 0; y < scans; y++)
|
|
|
|
{
|
|
|
|
for (x = 0; x < w; x++)
|
|
|
|
{
|
|
|
|
*ptr2 =
|
|
|
|
((*ptr2) & 0x00ffffff) |
|
|
|
|
((ptr[0]) << 24);
|
|
|
|
ptr++;
|
|
|
|
ptr2++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
/* end data decoding */
|
|
|
|
jpeg_finish_decompress(&cinfo);
|
|
|
|
jpeg_destroy_decompress(&cinfo);
|
2009-12-22 15:11:57 -08:00
|
|
|
*error = EVAS_LOAD_ERROR_NONE;
|
|
|
|
return EINA_TRUE;
|
2006-01-14 12:03:42 -08:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2009-12-22 15:11:57 -08:00
|
|
|
static Eina_Bool
|
2011-06-07 06:34:18 -07:00
|
|
|
evas_image_load_file_head_jpeg(Image_Entry *ie,
|
|
|
|
const char *file, const char *key __UNUSED__,
|
|
|
|
int *error)
|
2006-01-14 12:03:42 -08:00
|
|
|
{
|
2011-06-07 06:34:18 -07:00
|
|
|
Eina_File *f;
|
|
|
|
void *map;
|
|
|
|
Eina_Bool val = EINA_FALSE;
|
2006-01-14 12:03:42 -08:00
|
|
|
|
2011-06-07 06:34:18 -07:00
|
|
|
f = eina_file_open(file, EINA_FALSE);
|
2009-12-22 15:11:57 -08:00
|
|
|
if (!f)
|
|
|
|
{
|
|
|
|
*error = EVAS_LOAD_ERROR_DOES_NOT_EXIST;
|
|
|
|
return EINA_FALSE;
|
|
|
|
}
|
2011-06-07 06:34:18 -07:00
|
|
|
map = eina_file_map_all(f, EINA_FILE_WILLNEED);
|
|
|
|
if (!map)
|
|
|
|
{
|
|
|
|
*error = EVAS_LOAD_ERROR_DOES_NOT_EXIST;
|
|
|
|
goto on_error;
|
|
|
|
}
|
|
|
|
|
|
|
|
val = evas_image_load_file_head_jpeg_internal(ie,
|
|
|
|
map, eina_file_size_get(f),
|
|
|
|
error);
|
|
|
|
|
|
|
|
eina_file_map_free(f, map);
|
|
|
|
|
|
|
|
on_error:
|
|
|
|
eina_file_close(f);
|
2006-01-14 12:03:42 -08:00
|
|
|
return val;
|
|
|
|
}
|
|
|
|
|
2009-12-22 15:11:57 -08:00
|
|
|
static Eina_Bool
|
2011-06-07 06:34:18 -07:00
|
|
|
evas_image_load_file_data_jpeg(Image_Entry *ie,
|
|
|
|
const char *file, const char *key __UNUSED__,
|
|
|
|
int *error)
|
2006-01-14 12:03:42 -08:00
|
|
|
{
|
2011-06-07 06:34:18 -07:00
|
|
|
Eina_File *f;
|
|
|
|
void *map;
|
|
|
|
Eina_Bool val = EINA_FALSE;
|
2006-01-14 12:03:42 -08:00
|
|
|
|
2011-06-07 06:34:18 -07:00
|
|
|
f = eina_file_open(file, EINA_FALSE);
|
2009-12-22 15:11:57 -08:00
|
|
|
if (!f)
|
|
|
|
{
|
|
|
|
*error = EVAS_LOAD_ERROR_DOES_NOT_EXIST;
|
|
|
|
return EINA_FALSE;
|
|
|
|
}
|
2011-06-07 06:34:18 -07:00
|
|
|
map = eina_file_map_all(f, EINA_FILE_WILLNEED);
|
|
|
|
if (!map)
|
|
|
|
{
|
|
|
|
*error = EVAS_LOAD_ERROR_DOES_NOT_EXIST;
|
|
|
|
goto on_error;
|
|
|
|
}
|
|
|
|
|
|
|
|
val = evas_image_load_file_data_jpeg_internal(ie,
|
|
|
|
map, eina_file_size_get(f),
|
|
|
|
error);
|
|
|
|
|
|
|
|
eina_file_map_free(f, map);
|
|
|
|
|
|
|
|
on_error:
|
|
|
|
eina_file_close(f);
|
2006-01-14 12:03:42 -08:00
|
|
|
return val;
|
|
|
|
}
|
|
|
|
|
2009-06-16 06:01:36 -07:00
|
|
|
static int
|
2006-09-06 00:28:46 -07:00
|
|
|
module_open(Evas_Module *em)
|
2006-01-14 12:03:42 -08:00
|
|
|
{
|
|
|
|
if (!em) return 0;
|
|
|
|
em->functions = (void *)(&evas_image_load_jpeg_func);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2009-06-16 06:01:36 -07:00
|
|
|
static void
|
cleanup: fix some "unused" errors from -Wextra.
As we're heading for a release we better remove as much errors as
possible and as the first step I'm removing warnings due unused
parameters, variables and functions. These tend to pollute real errors
spotted by -Wall and clang/llvm.
This does not fixes all, just the clear that could be set to
__UNUSED__, particularly to do (and I'd like some help from the
authors):
* src/lib/engines/common/evas_font_{draw,query}.c (tasn):
intl_props is just used while doing BIDI, but also used in other
#ifdef blocks :-/
* evas_map_* (raster):
huge amount of warnings, code is quite confusing and thus I'm not
touching it. I have no idea whenever the commented blocks or extra
parameters are intended to be used or no.
* src/modules/engines/fbevas_fb_main.c (raster?):
is fb_setvt() to be used? If not do you mind removing it?
* src/modules/engines/gl_{common,x11} (raster):
huge amount of warnings, code is quite nested and full of #ifdefs
that does not help to give a clear picture of what's going on.
* src/bin/evas_cserve_main.c (raster):
I could have ignored most of the errors, but is the code correct? I
mean, there is no unload of images being applied. If you confirm
none of those warnings are harmful I can flag them as unused.
* src/lib/engines/common_8 (dottedmag):
lots of unused functions that were acquired from common_16, they
are unused and if they will not, then they should be removed.
SVN revision: 52421
2010-09-18 12:17:41 -07:00
|
|
|
module_close(Evas_Module *em __UNUSED__)
|
2006-01-14 12:03:42 -08:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2009-06-16 06:01:36 -07:00
|
|
|
static Evas_Module_Api evas_modapi =
|
2006-01-14 12:03:42 -08:00
|
|
|
{
|
|
|
|
EVAS_MODULE_API_VERSION,
|
2009-06-16 06:01:36 -07:00
|
|
|
"jpeg",
|
|
|
|
"none",
|
|
|
|
{
|
|
|
|
module_open,
|
|
|
|
module_close
|
|
|
|
}
|
2006-01-14 12:03:42 -08:00
|
|
|
};
|
2009-06-16 06:01:36 -07:00
|
|
|
|
|
|
|
EVAS_MODULE_DEFINE(EVAS_MODULE_TYPE_IMAGE_LOADER, image_loader, jpeg);
|
|
|
|
|
|
|
|
#ifndef EVAS_STATIC_BUILD_JPEG
|
|
|
|
EVAS_EINA_MODULE_DEFINE(image_loader, jpeg);
|
|
|
|
#endif
|
|
|
|
|