Skip to content

Commit 59c2bc7

Browse files
authored
added CMYK/YCCK support for JPGs (#1731)
added CMYK/YCCK support Fixes #1720
1 parent 56c1619 commit 59c2bc7

File tree

2 files changed

+34
-13
lines changed

2 files changed

+34
-13
lines changed

addons/image/jpg.c

Lines changed: 34 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -190,14 +190,27 @@ static void load_jpg_entry_helper(ALLEGRO_FILE *fp,
190190
jpeg_create_decompress(&cinfo);
191191
jpeg_packfile_src(&cinfo, fp, data->buffer);
192192
jpeg_read_header(&cinfo, true);
193+
194+
switch (cinfo.jpeg_color_space) {
195+
case JCS_CMYK:
196+
case JCS_YCCK:
197+
/* CMYK and YCCK to RGB conversion isn't supported. This also converts YCCK to CMYK. */
198+
cinfo.out_color_space = JCS_CMYK;
199+
break;
200+
default:
201+
/* libjpeg can convert most other color spaces to RGB. */
202+
cinfo.out_color_space = JCS_RGB;
203+
break;
204+
}
205+
193206
jpeg_start_decompress(&cinfo);
194207

195208
w = cinfo.output_width;
196209
h = cinfo.output_height;
197210
s = cinfo.output_components;
198211

199-
/* Only one and three components make sense in a JPG file. */
200-
if (s != 1 && s != 3) {
212+
/* Only three or four components make sense at this point. */
213+
if (s != 3 && s != 4) {
201214
data->error = true;
202215
ALLEGRO_ERROR("%d components makes no sense\n", s);
203216
goto error;
@@ -237,22 +250,30 @@ static void load_jpg_entry_helper(ALLEGRO_FILE *fp,
237250
jpeg_read_scanlines(&cinfo, (void *)out, 1);
238251
}
239252
}
240-
else if (s == 1) {
241-
/* Greyscale. */
242-
unsigned char *in;
243-
unsigned char *out;
253+
else if (s == 4) {
254+
/* CMYK. */
244255
int x, y;
256+
data->row = al_malloc(w * 4);
257+
258+
if (data->row == NULL) {
259+
data->error = true;
260+
ALLEGRO_ERROR("failed to allocate row buffer\n");
261+
goto error;
262+
}
245263

246-
data->row = al_malloc(w);
247264
for (y = cinfo.output_scanline; y < h; y = cinfo.output_scanline) {
265+
unsigned char *dest_row;
248266
jpeg_read_scanlines(&cinfo, (void *)&data->row, 1);
249-
in = data->row;
250-
out = ((unsigned char *)lock->data) + y * lock->pitch;
267+
dest_row = ((unsigned char *)lock->data) + y * lock->pitch;
251268
for (x = 0; x < w; x++) {
252-
*out++ = *in;
253-
*out++ = *in;
254-
*out++ = *in;
255-
in++;
269+
/* libjpeg outputs inverted CMYK where 255 = no ink. */
270+
unsigned char c = data->row[x * 4 + 0];
271+
unsigned char m = data->row[x * 4 + 1];
272+
unsigned char y2 = data->row[x * 4 + 2];
273+
unsigned char k = data->row[x * 4 + 3];
274+
dest_row[x * 3 + 0] = (unsigned char)(c * k / 255);
275+
dest_row[x * 3 + 1] = (unsigned char)(m * k / 255);
276+
dest_row[x * 3 + 2] = (unsigned char)(y2 * k / 255);
256277
}
257278
}
258279
}

examples/data/alexlogo_cmyk.jpg

2.65 MB
Loading

0 commit comments

Comments
 (0)