return 0;
}
+/*! 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
+}ExifByteAlign;
+
+static int
+_get_orientation(const char *path)
+{
+ if (!path) return 0;
+
+ /* open file and get 22type frome file */
+
+ FILE *f;
+ int size;
+ unsigned char buf[4096];
+ unsigned char orientation[2];
+ ExifByteAlign byte_align;
+ int num_directory = 0;
+ int i, j;
+ int direction;
+
+ f = fopen (path, "rb");
+ if (!f) return 0;
+
+ /* 1. read 22byte */
+ size = fread (buf, 1, 22, f);
+
+ if (size < 22)
+ {
+ fclose(f);
+ return 0;
+ }
+
+ /* 2. check 2,3 bypte with APP1(0xFFE1) */
+ if (memcmp(buf + 2, App1, sizeof (App1)))
+ {
+ fclose(f);
+ return 0;
+ }
+
+ /* 3. check 6~11bype with Exif Header (0x45786966 0000) */
+ if (memcmp(buf + 6, ExifHeader, sizeof (ExifHeader)))
+ {
+ fclose(f);
+ 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
+ {
+ fclose(f);
+ return 0;
+ }
+
+ if (fread(buf, 12, num_directory, f) > 4096)
+ {
+ fclose(f);
+ return 0;
+ }
+ /* we get all info from file, close file first */
+ fclose(f);
+ 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;
+}
+
static Eina_Bool
evas_image_load_file_head_jpeg_internal(Image_Entry *ie,
void *map, size_t length,
struct jpeg_decompress_struct cinfo;
struct _JPEG_error_mgr jerr;
+ /* for rotation decoding */
+ int degree = 0;
+ Eina_Bool change_wh = EINA_FALSE;
+ unsigned int load_opts_w, load_opts_h;
+
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);
+ jpeg_destroy_decompress(&cinfo);
_evas_jpeg_membuf_src_term(&cinfo);
- if (cinfo.saw_JFIF_marker)
- *error = EVAS_LOAD_ERROR_CORRUPT_FILE;
- else
- *error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
- return EINA_FALSE;
+ if (cinfo.saw_JFIF_marker)
+ *error = EVAS_LOAD_ERROR_CORRUPT_FILE;
+ else
+ *error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
+ return EINA_FALSE;
}
jpeg_create_decompress(&cinfo);
cinfo.dither_mode = JDITHER_ORDERED;
jpeg_start_decompress(&cinfo);
-/* head decoding */
+ /* head decoding */
+ if (ie->load_opts.orientation)
+ {
+ degree = _get_orientation(ie->file);
+ if (degree != 0)
+ {
+ ie->load_opts.degree = degree;
+ ie->flags.rotated = EINA_TRUE;
+
+ if (degree == 90 || degree == 270)
+ change_wh = EINA_TRUE;
+ }
+
+ }
+ /* head decoding */
w = cinfo.output_width;
h = cinfo.output_height;
if ((w < 1) || (h < 1) || (w > IMG_MAX_SIZE) || (h > IMG_MAX_SIZE) ||
{
jpeg_destroy_decompress(&cinfo);
_evas_jpeg_membuf_src_term(&cinfo);
- if (IMG_TOO_BIG(w, h))
- *error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
- else
- *error = EVAS_LOAD_ERROR_GENERIC;
- return EINA_FALSE;
+ if (IMG_TOO_BIG(w, h))
+ *error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
+ else
+ *error = EVAS_LOAD_ERROR_GENERIC;
+ return EINA_FALSE;
}
if (ie->load_opts.scale_down_by > 1)
{
- w /= ie->load_opts.scale_down_by;
- h /= ie->load_opts.scale_down_by;
+ w /= ie->load_opts.scale_down_by;
+ h /= ie->load_opts.scale_down_by;
}
else if (ie->load_opts.dpi > 0.0)
{
- w = (w * ie->load_opts.dpi) / 90.0;
- h = (h * ie->load_opts.dpi) / 90.0;
+ w = (w * ie->load_opts.dpi) / 90.0;
+ h = (h * ie->load_opts.dpi) / 90.0;
}
else if ((ie->load_opts.w > 0) && (ie->load_opts.h > 0))
{
- unsigned int w2 = w, h2 = h;
- 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))
- {
- unsigned int w3;
- h2 = ie->load_opts.h;
- w3 = (ie->load_opts.h * w) / h;
- if (w3 > w2)
- w2 = w3;
- }
- }
- else if (ie->load_opts.h > 0)
- {
- h2 = ie->load_opts.h;
- w2 = (ie->load_opts.h * w) / h;
- }
- w = w2;
- h = h2;
+ 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;
+ }
+
+ 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))
+ {
+ unsigned int w3;
+ h2 = ie->load_opts.h;
+ w3 = (ie->load_opts.h * w) / h;
+ if (w3 > w2)
+ w2 = w3;
+ }
+ }
+ else if (ie->load_opts.h > 0)
+ {
+ h2 = ie->load_opts.h;
+ w2 = (ie->load_opts.h * w) / h;
+ }
+ w = w2;
+ h = h2;
+ if (change_wh)
+ {
+ ie->load_opts.w = load_opts_w;
+ ie->load_opts.h = load_opts_h;
+ }
}
if (w < 1) w = 1;
if (h < 1) h = 1;
if ((w != cinfo.output_width) || (h != cinfo.output_height))
{
- scalew = cinfo.output_width / w;
- scaleh = cinfo.output_height / h;
+ scalew = cinfo.output_width / w;
+ scaleh = cinfo.output_height / h;
- ie->scale = scalew;
- if (scaleh < scalew) ie->scale = scaleh;
+ ie->scale = scalew;
+ if (scaleh < scalew) ie->scale = scaleh;
- if (ie->scale > 8) ie->scale = 8;
- else if (ie->scale < 1) ie->scale = 1;
+ if (ie->scale > 8) ie->scale = 8;
+ else if (ie->scale < 1) ie->scale = 1;
- 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;
+ 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;
}
if (ie->scale > 1)
{
- jpeg_destroy_decompress(&cinfo);
+ jpeg_destroy_decompress(&cinfo);
_evas_jpeg_membuf_src_term(&cinfo);
- jpeg_create_decompress(&cinfo);
+ jpeg_create_decompress(&cinfo);
if (_evas_jpeg_membuf_src(&cinfo, map, length))
{
return EINA_FALSE;
}
- jpeg_read_header(&cinfo, TRUE);
- cinfo.do_fancy_upsampling = FALSE;
- cinfo.do_block_smoothing = FALSE;
- cinfo.scale_num = 1;
- cinfo.scale_denom = ie->scale;
- jpeg_calc_output_dimensions(&(cinfo));
- jpeg_start_decompress(&cinfo);
+ jpeg_read_header(&cinfo, TRUE);
+ cinfo.do_fancy_upsampling = FALSE;
+ cinfo.do_block_smoothing = FALSE;
+ cinfo.scale_num = 1;
+ cinfo.scale_denom = ie->scale;
+ jpeg_calc_output_dimensions(&(cinfo));
+ jpeg_start_decompress(&cinfo);
}
ie->w = cinfo.output_width;
ie->h = cinfo.output_height;
-
+
// 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))
{
+ unsigned int load_region_x, load_region_y,load_region_w,load_region_h;
+ 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: //done
+ 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: //done
+ 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;
+ }
+
+ }
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);
{
jpeg_destroy_decompress(&cinfo);
_evas_jpeg_membuf_src_term(&cinfo);
- *error = EVAS_LOAD_ERROR_GENERIC;
- return EINA_FALSE;
+ *error = EVAS_LOAD_ERROR_GENERIC;
+ return EINA_FALSE;
}
ie->w = ie->load_opts.region.w;
ie->h = ie->load_opts.region.h;
+ 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;
+ }
+ }
+ /* end head decoding */
+ if (change_wh)
+ {
+ unsigned int tmp;
+ tmp = ie->w;
+ ie->w = ie->h;
+ ie->h = tmp;
}
-/* end head decoding */
-
jpeg_destroy_decompress(&cinfo);
_evas_jpeg_membuf_src_term(&cinfo);
*error = EVAS_LOAD_ERROR_NONE;
}
/*
-static double
-get_time(void)
-{
+ static double
+ get_time(void)
+ {
struct timeval timev;
-
+
gettimeofday(&timev, NULL);
return (double)timev.tv_sec + (((double)timev.tv_usec) / 1000000);
-}
-*/
+ }
+ */
static Eina_Bool
evas_image_load_file_data_jpeg_internal(Image_Entry *ie,
struct jpeg_decompress_struct cinfo;
struct _JPEG_error_mgr jerr;
DATA8 *ptr, *line[16], *data;
- DATA32 *ptr2;
+ DATA32 *ptr2,*ptr_rotate;
unsigned int x, y, l, i, scans;
int region = 0;
+ unsigned int tmp, load_region_x, load_region_y, load_region_w, load_region_h;/* for rotation decoding */
+ /* rotation setting */
+ int degree = 0;
+ Eina_Bool change_wh = EINA_FALSE;
+ Eina_Bool line_done = EINA_FALSE;
+ if (ie->flags.rotated)
+ {
+ degree = ie->load_opts.degree;
+ if (degree == 90 || degree == 270)
+ change_wh = EINA_TRUE;
+ }
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);
+ jpeg_destroy_decompress(&cinfo);
_evas_jpeg_membuf_src_term(&cinfo);
- *error = EVAS_LOAD_ERROR_CORRUPT_FILE;
- return EINA_FALSE;
+ *error = EVAS_LOAD_ERROR_CORRUPT_FILE;
+ return EINA_FALSE;
}
jpeg_create_decompress(&cinfo);
if (ie->scale > 1)
{
- cinfo.scale_num = 1;
- cinfo.scale_denom = ie->scale;
+ cinfo.scale_num = 1;
+ cinfo.scale_denom = ie->scale;
}
/* Colorspace conversion options */
/* 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;
+ 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;
}
-/* head decoding */
+ /* head decoding */
jpeg_calc_output_dimensions(&(cinfo));
jpeg_start_decompress(&cinfo);
w = cinfo.output_width;
h = cinfo.output_height;
+ if (change_wh)
+ {
+ tmp = ie->w;
+ ie->w = ie->h;
+ ie->h = tmp;
+ }
+
if ((ie->load_opts.region.w > 0) && (ie->load_opts.region.h > 0))
{
region = 1;
#ifdef BUILD_LOADER_JPEG_REGION
+
+ 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: //done
+ 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: //done
+ 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;
+ }
+
+ }
cinfo.region_x = ie->load_opts.region.x;
cinfo.region_y = ie->load_opts.region.y;
cinfo.region_w = ie->load_opts.region.w;
}
if ((!region) && ((w != ie->w) || (h != ie->h)))
{
- // 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);
+ // 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);
_evas_jpeg_membuf_src_term(&cinfo);
- *error = EVAS_LOAD_ERROR_GENERIC;
- return EINA_FALSE;
+ *error = EVAS_LOAD_ERROR_GENERIC;
+ return EINA_FALSE;
}
if ((region) &&
((ie->w != ie->load_opts.region.w) || (ie->h != ie->load_opts.region.h)))
((cinfo.output_components == 3) || (cinfo.output_components == 1))) ||
((cinfo.out_color_space == JCS_CMYK) && (cinfo.output_components == 4))))
{
- jpeg_destroy_decompress(&cinfo);
+ jpeg_destroy_decompress(&cinfo);
_evas_jpeg_membuf_src_term(&cinfo);
- *error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
- return EINA_FALSE;
+ *error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
+ return EINA_FALSE;
}
-/* end head decoding */
-/* data decoding */
+ /* end head decoding */
+ /* data decoding */
if (cinfo.rec_outbuf_height > 16)
{
- jpeg_destroy_decompress(&cinfo);
+ jpeg_destroy_decompress(&cinfo);
_evas_jpeg_membuf_src_term(&cinfo);
- *error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
- return EINA_FALSE;
+ *error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
+ return EINA_FALSE;
}
data = alloca(w * 16 * cinfo.output_components);
evas_cache_image_surface_alloc(ie, ie->w, ie->h);
if (ie->flags.loaded)
{
- jpeg_destroy_decompress(&cinfo);
+ jpeg_destroy_decompress(&cinfo);
_evas_jpeg_membuf_src_term(&cinfo);
- *error = EVAS_LOAD_ERROR_NONE;
- return EINA_TRUE;
+ *error = EVAS_LOAD_ERROR_NONE;
+ if (region && ie->flags.rotated)
+ {
+ ie->load_opts.region.x = load_region_x;
+ ie->load_opts.region.y = load_region_x;
+ ie->load_opts.region.w = load_region_x;
+ ie->load_opts.region.h = load_region_x;
+ }
+ return EINA_TRUE;
}
- ptr2 = evas_cache_image_pixels(ie);
+ if ((ie->flags.rotated) && change_wh)
+ {
+ ptr2 = malloc(ie->w * ie->h * sizeof(DATA32));
+ ptr_rotate = ptr2;
+ }
+ else
+ ptr2 = evas_cache_image_pixels(ie);
if (!ptr2)
{
*error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
if (cinfo.output_components == 4)
{
// FIXME: handle region
- for (i = 0; (int)i < cinfo.rec_outbuf_height; i++)
- 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;
+ for (i = 0; (int)i < cinfo.rec_outbuf_height; i++)
+ 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;
if (!region)
{
for (y = 0; y < scans; y++)
/* 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));
+ (0xff000000) |
+ ((ptr[0] * ptr[3] / 255) << 16) |
+ ((ptr[1] * ptr[3] / 255) << 8) |
+ ((ptr[2] * ptr[3] / 255));
ptr += 4;
ptr2++;
}
/* 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));
+ (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++;
}
}
- }
- }
+ }
+ }
else
{
// if line # > region last line, break
if (l >= (ie->load_opts.region.y + ie->load_opts.region.h))
{
- jpeg_destroy_decompress(&cinfo);
- _evas_jpeg_membuf_src_term(&cinfo);
- *error = EVAS_LOAD_ERROR_NONE;
- return EINA_FALSE;
+ 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;*/
}
// els if scan block intersects region start or later
- else if ((l + scans) >
+ else if ((l + scans) >
(ie->load_opts.region.y))
{
for (y = 0; y < scans; y++)
/* 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));
+ (0xff000000) |
+ ((ptr[0] * ptr[3] / 255) << 16) |
+ ((ptr[1] * ptr[3] / 255) << 8) |
+ ((ptr[2] * ptr[3] / 255));
ptr += 4;
ptr2++;
}
/* 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));
+ (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++;
}
}
}
}
- }
+ }
}
/* We handle then RGB with 3 components */
else if (cinfo.output_components == 3)
{
-/*
- double t;
- if (region)
- {
- // debug for now
- printf("R| %p %5ix%5i %s: %5i %5i %5ix%5i - ",
- ie,
- 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);
- }
+ /*
+ double t;
+ if (region)
+ {
+ // debug for now
+ printf("R| %p %5ix%5i %s: %5i %5i %5ix%5i - ",
+ ie,
+ 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);
+ }
t = get_time();
- */
+ */
for (i = 0; (int)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;
+ 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;
if (!region)
{
for (y = 0; y < scans; y++)
ptr2++;
}
}
- }
+ }
else
{
// if line # > region last line, break
+ // but not return immediately for rotation job
if (l >= (ie->load_opts.region.y + ie->load_opts.region.h))
{
- jpeg_destroy_decompress(&cinfo);
- _evas_jpeg_membuf_src_term(&cinfo);
-/*
- t = get_time() - t;
- printf("%3.3f\n", t);
- */
- *error = EVAS_LOAD_ERROR_NONE;
- return EINA_TRUE;
+ line_done = EINA_TRUE;
+ /* if rotation flag is set , we have to rotate image */
+ goto done;
}
// else if scan block intersects region start or later
- else if ((l + scans) >
+ else if ((l + scans) >
(ie->load_opts.region.y))
{
for (y = 0; y < scans; y++)
}
}
}
- }
-/*
- t = get_time() - t;
- printf("%3.3f\n", t);
- */
+ }
+ /*
+ t = get_time() - t;
+ printf("%3.3f\n", t);
+ */
}
/* We finally handle RGB with 1 component */
else if (cinfo.output_components == 1)
{
- for (i = 0; (int)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 (i = 0; (int)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;
if (!region)
{
for (y = 0; y < scans; y++)
ptr2++;
}
}
- }
+ }
else
{
// if line # > region last line, break
if (l >= (ie->load_opts.region.y + ie->load_opts.region.h))
{
- jpeg_destroy_decompress(&cinfo);
- _evas_jpeg_membuf_src_term(&cinfo);
- *error = EVAS_LOAD_ERROR_NONE;
- return EINA_TRUE;
+ 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;*/
}
// els if scan block intersects region start or later
- else if ((l + scans) >
+ else if ((l + scans) >
(ie->load_opts.region.y))
{
for (y = 0; y < scans; y++)
}
}
}
- }
+ }
}
-/* end data decoding */
+ /* if rotation operation need, rotate it */
+done:
+ if (ie->flags.rotated)
+ {
+ DATA32 *data1, *data2, *to, *from;
+ int x, y, w, h, hw;
+
+ if (change_wh)
+ {
+ tmp = ie->w;
+ ie->w = ie->h;
+ ie->h = tmp;
+ }
+
+ w = ie->w;
+ h = ie->h;
+ hw =w * h;
+
+ data1 = evas_cache_image_pixels(ie);
+
+ if (degree == 180)
+ {
+ DATA32 tmp;
+
+ data2 = data1 + (h * w) -1;
+ for (x = (w * h) / 2; --x >= 0;)
+ {
+ tmp = *data1;
+ *data1 = *data2;
+ *data2 = tmp;
+ data1++;
+ data2--;
+ }
+ }
+ else
+ {
+ data2 = ptr_rotate;
+
+ if (degree == 90)
+ {
+ to = data1 + w - 1;
+ hw = -hw - 1;
+ }
+
+ else if (degree == 270)
+ {
+ to = data1 + hw - w;
+ w = -w;
+ hw = hw + 1;
+ }
+
+ from = data2;
+ for (x = ie->w; --x >= 0;)
+ {
+ for (y =ie->h; --y >= 0;)
+ {
+ *to = *from;
+ from++;
+ to += w;
+ }
+ to += hw;
+ }
+ if (ptr_rotate)
+ {
+ free(ptr_rotate);
+ ptr_rotate = NULL;
+ }
+
+ }
+ if (region )
+ {
+ ie->load_opts.region.x = load_region_x;
+ ie->load_opts.region.y = load_region_x;
+ ie->load_opts.region.w = load_region_x;
+ ie->load_opts.region.h = load_region_x;
+ }
+ }
+
+ if (line_done)
+ {
+ jpeg_destroy_decompress(&cinfo);
+ _evas_jpeg_membuf_src_term(&cinfo);
+ *error = EVAS_LOAD_ERROR_NONE;
+ return EINA_FALSE;
+ }
+ /* end data decoding */
jpeg_finish_decompress(&cinfo);
jpeg_destroy_decompress(&cinfo);
_evas_jpeg_membuf_src_term(&cinfo);
if (!f)
{
- *error = EVAS_LOAD_ERROR_DOES_NOT_EXIST;
- return EINA_FALSE;
+ *error = EVAS_LOAD_ERROR_DOES_NOT_EXIST;
+ return EINA_FALSE;
}
cinfo.err = jpeg_std_error(&(jerr.pub));
jerr.pub.error_exit = _JPEGFatalErrorHandler;
jerr.pub.output_message = _JPEGErrorHandler;
if (setjmp(jerr.setjmp_buffer))
{
- jpeg_destroy_decompress(&cinfo);
- *error = EVAS_LOAD_ERROR_CORRUPT_FILE;
- return EINA_FALSE;
+ jpeg_destroy_decompress(&cinfo);
+ *error = EVAS_LOAD_ERROR_CORRUPT_FILE;
+ return EINA_FALSE;
}
jpeg_create_decompress(&cinfo);
jpeg_stdio_src(&cinfo, f);
cinfo.do_block_smoothing = FALSE;
jpeg_start_decompress(&cinfo);
-/* head decoding */
+ /* head decoding */
ie->w = w = cinfo.output_width;
ie->h = h = cinfo.output_height;
-/* end head decoding */
-/* data decoding */
+ /* end head decoding */
+ /* data decoding */
if (cinfo.rec_outbuf_height > 16)
{
- jpeg_destroy_decompress(&cinfo);
- *error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
- return EINA_FALSE;;
+ jpeg_destroy_decompress(&cinfo);
+ *error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
+ return EINA_FALSE;;
}
data = alloca(w * 16 * 3);
if (!ie->flags.loaded)
{
- jpeg_destroy_decompress(&cinfo);
- *error = EVAS_LOAD_ERROR_NONE;
- return EINA_TRUE;
+ jpeg_destroy_decompress(&cinfo);
+ *error = EVAS_LOAD_ERROR_NONE;
+ return EINA_TRUE;
}
ptr2 = evas_cache_image_pixels(ie);
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++;
- }
- }
- }
+ 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 */
+ 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);
*error = EVAS_LOAD_ERROR_NONE;
f = eina_file_open(file, EINA_FALSE);
if (!f)
{
- *error = EVAS_LOAD_ERROR_DOES_NOT_EXIST;
- return EINA_FALSE;
+ *error = EVAS_LOAD_ERROR_DOES_NOT_EXIST;
+ return EINA_FALSE;
}
map = eina_file_map_all(f, EINA_FILE_WILLNEED);
if (!map)
{
- *error = EVAS_LOAD_ERROR_DOES_NOT_EXIST;
+ *error = EVAS_LOAD_ERROR_DOES_NOT_EXIST;
goto on_error;
}
eina_file_map_free(f, map);
- on_error:
+on_error:
eina_file_close(f);
return val;
}
f = eina_file_open(file, EINA_FALSE);
if (!f)
{
- *error = EVAS_LOAD_ERROR_DOES_NOT_EXIST;
- return EINA_FALSE;
+ *error = EVAS_LOAD_ERROR_DOES_NOT_EXIST;
+ return EINA_FALSE;
}
map = eina_file_map_all(f, EINA_FILE_WILLNEED);
if (!map)
eina_file_map_free(f, map);
- on_error:
+on_error:
eina_file_close(f);
return val;
}
"jpeg",
"none",
{
- module_open,
- module_close
+ module_open,
+ module_close
}
};