@@ -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 }
0 commit comments