cjpeg: auto. compr. gray BMP/GIF-->grayscale JPEG

aa7459050d was supposed to enable this for
BMP input images but didn't, due to a similar oversight to the one fixed
in the previous commit.
This commit is contained in:
DRC
2021-11-30 15:06:54 -06:00
parent 2ce32e0fe5
commit 73eff6effe
5 changed files with 50 additions and 28 deletions

View File

@@ -7,6 +7,9 @@
input files into full-color JPEG images unless the `-grayscale` option was input files into full-color JPEG images unless the `-grayscale` option was
used. used.
2. cjpeg now automatically compresses GIF and 8-bit BMP input files into
grayscale JPEG images if the input files contain only shades of gray.
2.1.2 2.1.2
===== =====

View File

@@ -1,4 +1,4 @@
.TH CJPEG 1 "18 November 2021" .TH CJPEG 1 "30 November 2021"
.SH NAME .SH NAME
cjpeg \- compress an image file to a JPEG file cjpeg \- compress an image file to a JPEG file
.SH SYNOPSIS .SH SYNOPSIS
@@ -40,11 +40,7 @@ Scale quantization tables to adjust image quality. Quality is 0 (worst) to
100 (best); default is 75. (See below for more info.) 100 (best); default is 75. (See below for more info.)
.TP .TP
.B \-grayscale .B \-grayscale
Create monochrome JPEG file from color input. Be sure to use this switch when Create monochrome JPEG file from color input. By saying
compressing a grayscale BMP or GIF file, because
.B cjpeg
isn't bright enough to notice whether a BMP or GIF file uses only shades of
gray. By saying
.BR \-grayscale, .BR \-grayscale,
you'll get a smaller JPEG file that takes less time to process. you'll get a smaller JPEG file that takes less time to process.
.TP .TP

View File

@@ -125,7 +125,8 @@ read_colormap(bmp_source_ptr sinfo, int cmaplen, int mapentrysize)
break; break;
} }
if (sinfo->cinfo->in_color_space == JCS_UNKNOWN && gray) if ((sinfo->cinfo->in_color_space == JCS_UNKNOWN ||
sinfo->cinfo->in_color_space == JCS_RGB) && gray)
sinfo->cinfo->in_color_space = JCS_GRAYSCALE; sinfo->cinfo->in_color_space = JCS_GRAYSCALE;
if (sinfo->cinfo->in_color_space == JCS_GRAYSCALE && !gray) if (sinfo->cinfo->in_color_space == JCS_GRAYSCALE && !gray)

55
rdgif.c
View File

@@ -345,7 +345,7 @@ LOCAL(void)
ReadColorMap(gif_source_ptr sinfo, int cmaplen, JSAMPARRAY cmap) ReadColorMap(gif_source_ptr sinfo, int cmaplen, JSAMPARRAY cmap)
/* Read a GIF colormap */ /* Read a GIF colormap */
{ {
int i; int i, gray = 1;
for (i = 0; i < cmaplen; i++) { for (i = 0; i < cmaplen; i++) {
#if BITS_IN_JSAMPLE == 8 #if BITS_IN_JSAMPLE == 8
@@ -356,6 +356,14 @@ ReadColorMap(gif_source_ptr sinfo, int cmaplen, JSAMPARRAY cmap)
cmap[CM_RED][i] = (JSAMPLE)UPSCALE(ReadByte(sinfo)); cmap[CM_RED][i] = (JSAMPLE)UPSCALE(ReadByte(sinfo));
cmap[CM_GREEN][i] = (JSAMPLE)UPSCALE(ReadByte(sinfo)); cmap[CM_GREEN][i] = (JSAMPLE)UPSCALE(ReadByte(sinfo));
cmap[CM_BLUE][i] = (JSAMPLE)UPSCALE(ReadByte(sinfo)); cmap[CM_BLUE][i] = (JSAMPLE)UPSCALE(ReadByte(sinfo));
if (cmap[CM_RED][i] != cmap[CM_GREEN][i] ||
cmap[CM_GREEN][i] != cmap[CM_BLUE][i])
gray = 0;
}
if (sinfo->cinfo->in_color_space == JCS_RGB && gray) {
sinfo->cinfo->in_color_space = JCS_GRAYSCALE;
sinfo->cinfo->input_components = 1;
} }
} }
@@ -516,10 +524,15 @@ start_input_gif(j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
source->pub.get_pixel_rows = get_pixel_rows; source->pub.get_pixel_rows = get_pixel_rows;
} }
if (cinfo->in_color_space != JCS_GRAYSCALE) {
cinfo->in_color_space = JCS_RGB;
cinfo->input_components = NUMCOLORS;
}
/* Create compressor input buffer. */ /* Create compressor input buffer. */
source->pub.buffer = (*cinfo->mem->alloc_sarray) source->pub.buffer = (*cinfo->mem->alloc_sarray)
((j_common_ptr)cinfo, JPOOL_IMAGE, (JDIMENSION)width * NUMCOLORS, ((j_common_ptr)cinfo, JPOOL_IMAGE,
(JDIMENSION)1); (JDIMENSION)width * cinfo->input_components, (JDIMENSION)1);
source->pub.buffer_height = 1; source->pub.buffer_height = 1;
/* Pad colormap for safety. */ /* Pad colormap for safety. */
@@ -530,8 +543,6 @@ start_input_gif(j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
} }
/* Return info about the image. */ /* Return info about the image. */
cinfo->in_color_space = JCS_RGB;
cinfo->input_components = NUMCOLORS;
cinfo->data_precision = BITS_IN_JSAMPLE; /* we always rescale data to this */ cinfo->data_precision = BITS_IN_JSAMPLE; /* we always rescale data to this */
cinfo->image_width = width; cinfo->image_width = width;
cinfo->image_height = height; cinfo->image_height = height;
@@ -556,11 +567,18 @@ get_pixel_rows(j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
register JSAMPARRAY colormap = source->colormap; register JSAMPARRAY colormap = source->colormap;
ptr = source->pub.buffer[0]; ptr = source->pub.buffer[0];
for (col = cinfo->image_width; col > 0; col--) { if (cinfo->in_color_space == JCS_GRAYSCALE) {
c = LZWReadByte(source); for (col = cinfo->image_width; col > 0; col--) {
*ptr++ = colormap[CM_RED][c]; c = LZWReadByte(source);
*ptr++ = colormap[CM_GREEN][c]; *ptr++ = colormap[CM_RED][c];
*ptr++ = colormap[CM_BLUE][c]; }
} else {
for (col = cinfo->image_width; col > 0; col--) {
c = LZWReadByte(source);
*ptr++ = colormap[CM_RED][c];
*ptr++ = colormap[CM_GREEN][c];
*ptr++ = colormap[CM_BLUE][c];
}
} }
return 1; return 1;
} }
@@ -646,11 +664,18 @@ get_interlaced_row(j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
FALSE); FALSE);
/* Scan the row, expand colormap, and output */ /* Scan the row, expand colormap, and output */
ptr = source->pub.buffer[0]; ptr = source->pub.buffer[0];
for (col = cinfo->image_width; col > 0; col--) { if (cinfo->in_color_space == JCS_GRAYSCALE) {
c = *sptr++; for (col = cinfo->image_width; col > 0; col--) {
*ptr++ = colormap[CM_RED][c]; c = *sptr++;
*ptr++ = colormap[CM_GREEN][c]; *ptr++ = colormap[CM_RED][c];
*ptr++ = colormap[CM_BLUE][c]; }
} else {
for (col = cinfo->image_width; col > 0; col--) {
c = *sptr++;
*ptr++ = colormap[CM_RED][c];
*ptr++ = colormap[CM_GREEN][c];
*ptr++ = colormap[CM_BLUE][c];
}
} }
source->cur_row_number++; /* for next time */ source->cur_row_number++; /* for next time */
return 1; return 1;

View File

@@ -72,12 +72,9 @@ The basic command line switches for cjpeg are:
Quality is 0 (worst) to 100 (best); default is 75. Quality is 0 (worst) to 100 (best); default is 75.
(See below for more info.) (See below for more info.)
-grayscale Create monochrome JPEG file from color input. -grayscale Create monochrome JPEG file from color input. By
Be sure to use this switch when compressing a grayscale saying -grayscale, you'll get a smaller JPEG file that
BMP or GIF file, because cjpeg isn't bright enough to takes less time to process.
notice whether a BMP or GIF file uses only shades of
gray. By saying -grayscale, you'll get a smaller JPEG
file that takes less time to process.
-rgb Create RGB JPEG file. -rgb Create RGB JPEG file.
Using this switch suppresses the conversion from RGB Using this switch suppresses the conversion from RGB