int got_xres, got_yres, aspect_only, resunit;
double xres, yres;
int comment_entry;
+ int want_channels = im->channels;
struct jpeg_compress_struct cinfo;
struct my_error_mgr jerr;
JSAMPROW row_pointer[1]; /* pointer to JSAMPLE row[s] */
int row_stride; /* physical row width in image buffer */
unsigned char * data = NULL;
+ i_color *line_buf = NULL;
mm_log((1,"i_writejpeg(im %p, ig %p, qfactor %d)\n", im, ig, qfactor));
io_glue_commit_types(ig);
if (!(im->channels==1 || im->channels==3)) {
- i_push_error(0, "only 1 or 3 channels images can be saved as JPEG");
- return 0;
+ want_channels = im->channels - 1;
}
quality = qfactor;
jpeg_destroy_compress(&cinfo);
if (data)
myfree(data);
+ if (line_buf)
+ myfree(line_buf);
return 0;
}
cinfo.image_width = im -> xsize; /* image width and height, in pixels */
cinfo.image_height = im -> ysize;
- if (im->channels==3) {
+ if (want_channels==3) {
cinfo.input_components = 3; /* # of color components per pixel */
cinfo.in_color_space = JCS_RGB; /* colorspace of input image */
}
- if (im->channels==1) {
+ if (want_channels==1) {
cinfo.input_components = 1; /* # of color components per pixel */
cinfo.in_color_space = JCS_GRAYSCALE; /* colorspace of input image */
}
row_stride = im->xsize * im->channels; /* JSAMPLEs per row in image_buffer */
- if (!im->virtual && im->type == i_direct_type && im->bits == i_8_bits) {
+ if (!im->virtual && im->type == i_direct_type && im->bits == i_8_bits
+ && im->channels == want_channels) {
image_buffer=im->idata;
while (cinfo.next_scanline < cinfo.image_height) {
(void) jpeg_write_scanlines(&cinfo, row_pointer, 1);
}
}
- else {
+ else if (im->channels == want_channels) {
data = mymalloc(im->xsize * im->channels);
if (data) {
while (cinfo.next_scanline < cinfo.image_height) {
return 0; /* out of memory? */
}
}
+ else {
+ i_color bg;
+ int x;
+ int ch;
+ i_color const *linep;
+ unsigned char * datap;
+
+ line_buf = mymalloc(sizeof(i_color) * im->xsize);
+
+ i_get_file_background(im, &bg);
+
+ data = mymalloc(im->xsize * want_channels);
+ while (cinfo.next_scanline < cinfo.image_height) {
+ i_glin(im, 0, im->xsize, cinfo.next_scanline, line_buf);
+ i_adapt_colors_bg(want_channels, im->channels, line_buf, im->xsize, &bg);
+ datap = data;
+ linep = line_buf;
+ for (x = 0; x < im->xsize; ++x) {
+ for (ch = 0; ch < want_channels; ++ch) {
+ *datap++ = linep->channel[ch];
+ }
+ ++linep;
+ }
+ row_pointer[0] = data;
+ (void) jpeg_write_scanlines(&cinfo, row_pointer, 1);
+ }
+ myfree(line_buf);
+ myfree(data);
+ }
/* Step 6: Finish compression */