forked from old/legacy-imlib2
jpeg and png should do the right thing with quality _or_ compression now
SVN revision: 3789
This commit is contained in:
parent
490383f4d7
commit
2e758a7c94
|
@ -21,11 +21,12 @@ typedef struct ImLib_JPEG_error_mgr *emptr;
|
|||
void _JPEGFatalErrorHandler(j_common_ptr cinfo);
|
||||
void _JPEGErrorHandler(j_common_ptr cinfo);
|
||||
void _JPEGErrorHandler2(j_common_ptr cinfo, int msg_level);
|
||||
char load (ImlibImage *im, ImlibProgressFunction progress,
|
||||
char load(ImlibImage * im, ImlibProgressFunction progress,
|
||||
char progress_granularity, char immediate_load);
|
||||
char save (ImlibImage *im, ImlibProgressFunction progress,
|
||||
char save(ImlibImage * im, ImlibProgressFunction progress,
|
||||
|
||||
char progress_granularity);
|
||||
void formats (ImlibLoader *l);
|
||||
void formats(ImlibLoader * l);
|
||||
|
||||
void
|
||||
_JPEGFatalErrorHandler(j_common_ptr cinfo)
|
||||
|
@ -62,7 +63,7 @@ _JPEGErrorHandler2(j_common_ptr cinfo, int msg_level)
|
|||
}
|
||||
|
||||
char
|
||||
load (ImlibImage *im, ImlibProgressFunction progress,
|
||||
load(ImlibImage * im, ImlibProgressFunction progress,
|
||||
char progress_granularity, char immediate_load)
|
||||
{
|
||||
int w, h;
|
||||
|
@ -146,12 +147,11 @@ load (ImlibImage *im, ImlibProgressFunction progress,
|
|||
{
|
||||
for (x = 0; x < w; x++)
|
||||
{
|
||||
*ptr2 = (0xff000000) |
|
||||
((ptr[0]) << 16) |
|
||||
((ptr[1]) << 8) |
|
||||
*ptr2 =
|
||||
(0xff000000) | ((ptr[0]) << 16) | ((ptr[1]) << 8) |
|
||||
(ptr[2]);
|
||||
ptr += 3;
|
||||
ptr2 ++;
|
||||
ptr2++;
|
||||
}
|
||||
}
|
||||
if (progress)
|
||||
|
@ -159,11 +159,11 @@ load (ImlibImage *im, ImlibProgressFunction progress,
|
|||
int per;
|
||||
|
||||
per = (l * 100) / h;
|
||||
if (((per - count) >= progress_granularity) ||
|
||||
((h - l) <= cinfo.rec_outbuf_height))
|
||||
if (((per - count) >= progress_granularity)
|
||||
|| ((h - l) <= cinfo.rec_outbuf_height))
|
||||
{
|
||||
count = per;
|
||||
if(!progress(im, per, 0, prevy, w, scans + l - prevy))
|
||||
if (!progress(im, per, 0, prevy, w, scans + l - prevy))
|
||||
{
|
||||
free(data);
|
||||
jpeg_finish_decompress(&cinfo);
|
||||
|
@ -191,12 +191,11 @@ load (ImlibImage *im, ImlibProgressFunction progress,
|
|||
{
|
||||
for (x = 0; x < w; x++)
|
||||
{
|
||||
*ptr2 = (0xff000000) |
|
||||
((ptr[0]) << 16) |
|
||||
((ptr[0]) << 8) |
|
||||
*ptr2 =
|
||||
(0xff000000) | ((ptr[0]) << 16) | ((ptr[0]) << 8) |
|
||||
(ptr[0]);
|
||||
ptr ++;
|
||||
ptr2 ++;
|
||||
ptr++;
|
||||
ptr2++;
|
||||
}
|
||||
}
|
||||
if (progress)
|
||||
|
@ -204,11 +203,11 @@ load (ImlibImage *im, ImlibProgressFunction progress,
|
|||
int per;
|
||||
|
||||
per = (l * 100) / h;
|
||||
if (((per - count) >= progress_granularity) ||
|
||||
((h - l) <= cinfo.rec_outbuf_height))
|
||||
if (((per - count) >= progress_granularity)
|
||||
|| ((h - l) <= cinfo.rec_outbuf_height))
|
||||
{
|
||||
count = per;
|
||||
if(!progress(im, per, 0, prevy, w, l + scans - prevy))
|
||||
if (!progress(im, per, 0, prevy, w, l + scans - prevy))
|
||||
{
|
||||
free(data);
|
||||
jpeg_finish_decompress(&cinfo);
|
||||
|
@ -230,7 +229,7 @@ load (ImlibImage *im, ImlibProgressFunction progress,
|
|||
}
|
||||
|
||||
char
|
||||
save (ImlibImage *im, ImlibProgressFunction progress,
|
||||
save(ImlibImage * im, ImlibProgressFunction progress,
|
||||
char progress_granularity)
|
||||
{
|
||||
struct jpeg_compress_struct cinfo;
|
||||
|
@ -239,7 +238,7 @@ save (ImlibImage *im, ImlibProgressFunction progress,
|
|||
DATA8 *buf;
|
||||
DATA32 *ptr;
|
||||
JSAMPROW *jbuf;
|
||||
int y = 0, quality = 75;
|
||||
int y = 0, quality = 75, compression = 2;
|
||||
ImlibImageTag *tag;
|
||||
int i, j, pl = 0;
|
||||
char pper = 0;
|
||||
|
@ -281,6 +280,21 @@ save (ImlibImage *im, ImlibProgressFunction progress,
|
|||
/* look for tags attached to image to get extra parameters liek quality */
|
||||
/* settigns etc. - thsi si the "api" to hint for extra information for */
|
||||
/* saver modules */
|
||||
|
||||
/* compression */
|
||||
tag = __imlib_GetTag(im, "compression");
|
||||
if (tag)
|
||||
{
|
||||
compression = tag->val;
|
||||
if (compression < 0)
|
||||
compression = 0;
|
||||
if (compression > 9)
|
||||
compression = 9;
|
||||
}
|
||||
/* convert to quality */
|
||||
quality = (9 - compression) * 10;
|
||||
quality = quality * 10 / 9;
|
||||
/* quality */
|
||||
tag = __imlib_GetTag(im, "quality");
|
||||
if (tag)
|
||||
quality = tag->val;
|
||||
|
@ -302,12 +316,12 @@ save (ImlibImage *im, ImlibProgressFunction progress,
|
|||
for (j = 0, i = 0; i < im->w; i++)
|
||||
{
|
||||
buf[j++] = ((*ptr) >> 16) & 0xff;
|
||||
buf[j++] = ((*ptr) >> 8 ) & 0xff;
|
||||
buf[j++] = ((*ptr) ) & 0xff;
|
||||
buf[j++] = ((*ptr) >> 8) & 0xff;
|
||||
buf[j++] = ((*ptr)) & 0xff;
|
||||
ptr++;
|
||||
}
|
||||
/* write scanline */
|
||||
jbuf = (JSAMPROW *)(&buf);
|
||||
jbuf = (JSAMPROW *) (&buf);
|
||||
jpeg_write_scanlines(&cinfo, jbuf, 1);
|
||||
y++;
|
||||
if (progress)
|
||||
|
@ -315,12 +329,11 @@ save (ImlibImage *im, ImlibProgressFunction progress,
|
|||
char per;
|
||||
int l;
|
||||
|
||||
per = (char)((100 * y) / im->h);
|
||||
if (((per - pper) >= progress_granularity) ||
|
||||
(y == (im->h - 1)))
|
||||
per = (char) ((100 * y) / im->h);
|
||||
if (((per - pper) >= progress_granularity) || (y == (im->h - 1)))
|
||||
{
|
||||
l = y - pl;
|
||||
if(!progress(im, per, 0, (y - l), im->w, l))
|
||||
if (!progress(im, per, 0, (y - l), im->w, l))
|
||||
{
|
||||
jpeg_finish_compress(&cinfo);
|
||||
free(buf);
|
||||
|
@ -341,18 +354,17 @@ save (ImlibImage *im, ImlibProgressFunction progress,
|
|||
}
|
||||
|
||||
void
|
||||
formats (ImlibLoader *l)
|
||||
formats(ImlibLoader * l)
|
||||
{
|
||||
char *list_formats[] =
|
||||
{ "jpg", "jpeg", "jfif", "jfi" };
|
||||
char *list_formats[] = { "jpg", "jpeg", "jfif", "jfi" };
|
||||
|
||||
{
|
||||
int i;
|
||||
|
||||
l->num_formats = (sizeof(list_formats) / sizeof (char *));
|
||||
l->num_formats = (sizeof(list_formats) / sizeof(char *));
|
||||
l->formats = malloc(sizeof(char *) * l->num_formats);
|
||||
|
||||
for (i = 0; i < l->num_formats; i++)
|
||||
l->formats[i] = strdup(list_formats[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -15,14 +15,15 @@
|
|||
/* PNG stuff */
|
||||
#define PNG_BYTES_TO_CHECK 4
|
||||
|
||||
char load (ImlibImage *im, ImlibProgressFunction progress,
|
||||
char load(ImlibImage * im, ImlibProgressFunction progress,
|
||||
char progress_granularity, char immediate_load);
|
||||
char save (ImlibImage *im, ImlibProgressFunction progress,
|
||||
char save(ImlibImage * im, ImlibProgressFunction progress,
|
||||
|
||||
char progress_granularity);
|
||||
void formats (ImlibLoader *l);
|
||||
void formats(ImlibLoader * l);
|
||||
|
||||
char
|
||||
load (ImlibImage *im, ImlibProgressFunction progress,
|
||||
load(ImlibImage * im, ImlibProgressFunction progress,
|
||||
char progress_granularity, char immediate_load)
|
||||
{
|
||||
png_uint_32 w32, h32;
|
||||
|
@ -53,8 +54,8 @@ load (ImlibImage *im, ImlibProgressFunction progress,
|
|||
return 0;
|
||||
}
|
||||
rewind(f);
|
||||
png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL,
|
||||
NULL);
|
||||
png_ptr =
|
||||
png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
|
||||
if (!png_ptr)
|
||||
{
|
||||
fclose(f);
|
||||
|
@ -75,11 +76,11 @@ load (ImlibImage *im, ImlibProgressFunction progress,
|
|||
}
|
||||
png_init_io(png_ptr, f);
|
||||
png_read_info(png_ptr, info_ptr);
|
||||
png_get_IHDR(png_ptr, info_ptr,
|
||||
(png_uint_32 *)(&w32), (png_uint_32 *)(&h32),
|
||||
&bit_depth, &color_type, &interlace_type, NULL, NULL);
|
||||
im->w = (int)w32;
|
||||
im->h = (int)h32;
|
||||
png_get_IHDR(png_ptr, info_ptr, (png_uint_32 *) (&w32),
|
||||
(png_uint_32 *) (&h32), &bit_depth, &color_type,
|
||||
&interlace_type, NULL, NULL);
|
||||
im->w = (int) w32;
|
||||
im->h = (int) h32;
|
||||
if (color_type == PNG_COLOR_TYPE_PALETTE)
|
||||
png_set_expand(png_ptr);
|
||||
if (info_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
|
||||
|
@ -137,17 +138,18 @@ load (ImlibImage *im, ImlibProgressFunction progress,
|
|||
if (!im->data)
|
||||
{
|
||||
png_read_end(png_ptr, info_ptr);
|
||||
png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL);
|
||||
png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp) NULL);
|
||||
fclose(f);
|
||||
return 0;
|
||||
}
|
||||
lines = (unsigned char **)malloc(h * sizeof(unsigned char *));
|
||||
lines = (unsigned char **) malloc(h * sizeof(unsigned char *));
|
||||
|
||||
if (!lines)
|
||||
{
|
||||
free(im->data);
|
||||
im->data = NULL;
|
||||
png_read_end(png_ptr, info_ptr);
|
||||
png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL);
|
||||
png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp) NULL);
|
||||
fclose(f);
|
||||
return 0;
|
||||
}
|
||||
|
@ -162,7 +164,7 @@ load (ImlibImage *im, ImlibProgressFunction progress,
|
|||
free(lines);
|
||||
im->data = NULL;
|
||||
png_read_end(png_ptr, info_ptr);
|
||||
png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL);
|
||||
png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp) NULL);
|
||||
fclose(f);
|
||||
return 0;
|
||||
}
|
||||
|
@ -182,10 +184,8 @@ load (ImlibImage *im, ImlibProgressFunction progress,
|
|||
for (i = 0; i < w; i++)
|
||||
{
|
||||
ptr[0] =
|
||||
(line[i << 1] << 16) |
|
||||
(line[i << 1] << 8) |
|
||||
(line[i << 1]) |
|
||||
(line[(i << 1) + 1] << 24);
|
||||
(line[i << 1] << 16) | (line[i << 1] << 8) |
|
||||
(line[i << 1]) | (line[(i << 1) + 1] << 24);
|
||||
ptr++;
|
||||
}
|
||||
if (progress)
|
||||
|
@ -199,11 +199,13 @@ load (ImlibImage *im, ImlibProgressFunction progress,
|
|||
}
|
||||
}
|
||||
}
|
||||
if ((progress) && (!progress(im, per, 0, prevy, w, y - prevy + 1)))
|
||||
if ((progress)
|
||||
&& (!progress(im, per, 0, prevy, w, y - prevy + 1)))
|
||||
{
|
||||
free(lines);
|
||||
png_read_end(png_ptr, info_ptr);
|
||||
png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL);
|
||||
png_destroy_read_struct(&png_ptr, &info_ptr,
|
||||
(png_infopp) NULL);
|
||||
fclose(f);
|
||||
return 2;
|
||||
}
|
||||
|
@ -213,7 +215,8 @@ load (ImlibImage *im, ImlibProgressFunction progress,
|
|||
else
|
||||
{
|
||||
for (i = 0; i < h; i++)
|
||||
lines[i] = ((unsigned char *)(im->data)) + (i * w * sizeof(DATA32));
|
||||
lines[i] =
|
||||
((unsigned char *) (im->data)) + (i * w * sizeof(DATA32));
|
||||
if (progress)
|
||||
{
|
||||
int y, count, prevy, pass, number_passes, per, nrows = 1;
|
||||
|
@ -232,22 +235,24 @@ load (ImlibImage *im, ImlibProgressFunction progress,
|
|||
if ((per - count) >= progress_granularity)
|
||||
{
|
||||
count = per;
|
||||
if(!progress(im, per, 0, prevy, w, y - prevy + 1))
|
||||
if (!progress(im, per, 0, prevy, w, y - prevy + 1))
|
||||
{
|
||||
free(lines);
|
||||
png_read_end(png_ptr, info_ptr);
|
||||
png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL);
|
||||
png_destroy_read_struct(&png_ptr, &info_ptr,
|
||||
(png_infopp) NULL);
|
||||
fclose(f);
|
||||
return 2;
|
||||
}
|
||||
prevy = y + 1;
|
||||
}
|
||||
}
|
||||
if(!progress(im, per, 0, prevy, w, y - prevy + 1))
|
||||
if (!progress(im, per, 0, prevy, w, y - prevy + 1))
|
||||
{
|
||||
free(lines);
|
||||
png_read_end(png_ptr, info_ptr);
|
||||
png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL);
|
||||
png_destroy_read_struct(&png_ptr, &info_ptr,
|
||||
(png_infopp) NULL);
|
||||
fclose(f);
|
||||
return 2;
|
||||
}
|
||||
|
@ -259,13 +264,13 @@ load (ImlibImage *im, ImlibProgressFunction progress,
|
|||
free(lines);
|
||||
png_read_end(png_ptr, info_ptr);
|
||||
}
|
||||
png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL);
|
||||
png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp) NULL);
|
||||
fclose(f);
|
||||
return 1;
|
||||
}
|
||||
|
||||
char
|
||||
save (ImlibImage *im, ImlibProgressFunction progress,
|
||||
save(ImlibImage * im, ImlibProgressFunction progress,
|
||||
char progress_granularity)
|
||||
{
|
||||
FILE *f;
|
||||
|
@ -278,13 +283,12 @@ save (ImlibImage *im, ImlibProgressFunction progress,
|
|||
int pl = 0;
|
||||
char pper = 0;
|
||||
ImlibImageTag *tag;
|
||||
int quality = 75, compression;
|
||||
int quality = 75, compression = 3;
|
||||
|
||||
f = fopen(im->file, "wb");
|
||||
if (!f)
|
||||
return 0;
|
||||
png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING,
|
||||
NULL, NULL, NULL);
|
||||
png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
|
||||
if (!png_ptr)
|
||||
{
|
||||
fclose(f);
|
||||
|
@ -317,9 +321,9 @@ save (ImlibImage *im, ImlibProgressFunction progress,
|
|||
}
|
||||
else
|
||||
{
|
||||
png_set_IHDR(png_ptr, info_ptr, im->w, im->h, 8,
|
||||
PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE,
|
||||
PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
|
||||
png_set_IHDR(png_ptr, info_ptr, im->w, im->h, 8, PNG_COLOR_TYPE_RGB,
|
||||
PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE,
|
||||
PNG_FILTER_TYPE_BASE);
|
||||
data = malloc(im->w * 3 * sizeof(char));
|
||||
}
|
||||
sig_bit.red = 8;
|
||||
|
@ -327,18 +331,27 @@ save (ImlibImage *im, ImlibProgressFunction progress,
|
|||
sig_bit.blue = 8;
|
||||
sig_bit.alpha = 8;
|
||||
png_set_sBIT(png_ptr, info_ptr, &sig_bit);
|
||||
/* compression */
|
||||
/* quality */
|
||||
tag = __imlib_GetTag(im, "quality");
|
||||
if (tag)
|
||||
{
|
||||
quality = tag->val;
|
||||
if (quality < 10)
|
||||
quality = 10;
|
||||
if (quality < 1)
|
||||
quality = 1;
|
||||
if (quality > 99)
|
||||
quality = 99;
|
||||
/* translate to png-relevant value */
|
||||
}
|
||||
/* convert to compression */
|
||||
quality = quality / 10;
|
||||
compression = 10 - quality;
|
||||
/* should be 1-9 now */
|
||||
compression = 9 - quality;
|
||||
/* compression */
|
||||
tag = __imlib_GetTag(im, "compression");
|
||||
if (tag)
|
||||
compression = tag->val;
|
||||
if (compression < 0)
|
||||
compression = 0;
|
||||
if (compression > 9)
|
||||
compression = 9;
|
||||
png_set_compression_level(png_ptr, compression);
|
||||
png_write_info(png_ptr, info_ptr);
|
||||
png_set_shift(png_ptr, &sig_bit);
|
||||
|
@ -348,16 +361,16 @@ save (ImlibImage *im, ImlibProgressFunction progress,
|
|||
for (y = 0; y < im->h; y++)
|
||||
{
|
||||
if (im->flags & F_HAS_ALPHA)
|
||||
row_ptr = (png_bytep)ptr;
|
||||
row_ptr = (png_bytep) ptr;
|
||||
else
|
||||
{
|
||||
for (j = 0, x = 0; x < im->w; x++)
|
||||
{
|
||||
data[j++] = (ptr[x] >> 16) & 0xff;
|
||||
data[j++] = (ptr[x] >> 8 ) & 0xff;
|
||||
data[j++] = (ptr[x] ) & 0xff;
|
||||
data[j++] = (ptr[x] >> 8) & 0xff;
|
||||
data[j++] = (ptr[x]) & 0xff;
|
||||
}
|
||||
row_ptr = (png_bytep)data;
|
||||
row_ptr = (png_bytep) data;
|
||||
}
|
||||
png_write_rows(png_ptr, &row_ptr, 1);
|
||||
if (progress)
|
||||
|
@ -365,11 +378,11 @@ save (ImlibImage *im, ImlibProgressFunction progress,
|
|||
char per;
|
||||
int l;
|
||||
|
||||
per = (char)((100 * y) / im->h);
|
||||
per = (char) ((100 * y) / im->h);
|
||||
if ((per - pper) >= progress_granularity)
|
||||
{
|
||||
l = y - pl;
|
||||
if(!progress(im, per, 0, (y - l), im->w, l))
|
||||
if (!progress(im, per, 0, (y - l), im->w, l))
|
||||
{
|
||||
if (data)
|
||||
free(data);
|
||||
|
@ -401,21 +414,20 @@ save (ImlibImage *im, ImlibProgressFunction progress,
|
|||
/* loader->formats = { "gif", "png", "jpeg", "jpg"} */
|
||||
/* if it can load those formats. */
|
||||
void
|
||||
formats (ImlibLoader *l)
|
||||
formats(ImlibLoader * l)
|
||||
{
|
||||
/* this is the only bit you have to change... */
|
||||
char *list_formats[] =
|
||||
{ "png" };
|
||||
char *list_formats[] = { "png" };
|
||||
|
||||
/* don't bother changing any of this - it just reads this in and sets */
|
||||
/* the struct values and makes copies */
|
||||
{
|
||||
int i;
|
||||
|
||||
l->num_formats = (sizeof(list_formats) / sizeof (char *));
|
||||
l->num_formats = (sizeof(list_formats) / sizeof(char *));
|
||||
l->formats = malloc(sizeof(char *) * l->num_formats);
|
||||
|
||||
for (i = 0; i < l->num_formats; i++)
|
||||
l->formats[i] = strdup(list_formats[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue