diff --git a/cdjpeg.h b/cdjpeg.h
index 8c3b3b5d..a6532dc5 100644
--- a/cdjpeg.h
+++ b/cdjpeg.h
@@ -154,9 +154,5 @@ EXTERN(FILE *) write_stdout (void);
#define EXIT_WARNING 2
#endif
-#define RGB2GRAY(r, g, b) \
- (JSAMPLE)((double)(r) * 0.299 + (double)(g) * 0.587 + \
- (double)(b) * 0.114 + 0.5)
-
#define IsExtRGB(cs) \
(cs == JCS_RGB || (cs >= JCS_EXT_RGB && cs <= JCS_EXT_ARGB))
diff --git a/doc/html/group___turbo_j_p_e_g.html b/doc/html/group___turbo_j_p_e_g.html
index 4dc60309..40f8b286 100644
--- a/doc/html/group___turbo_j_p_e_g.html
+++ b/doc/html/group___turbo_j_p_e_g.html
@@ -2274,7 +2274,13 @@ If you choose option 1, *jpegSize should be set to the size of your
| width | pointer to an integer variable that will receive the width (in pixels) of the uncompressed image |
| align | row alignment of the image buffer to be returned (must be a power of 2.) For instance, setting this parameter to 4 will cause all rows in the image buffer to be padded to the nearest 32-bit boundary, and setting this parameter to 1 will cause all rows in the image buffer to be unpadded. |
| height | pointer to an integer variable that will receive the height (in pixels) of the uncompressed image |
- | pixelFormat | pointer to an integer variable that specifies or will receive the pixel format of the uncompressed image buffer. If *pixelFormat is set to TJPF_UNKNOWN prior to calling this function, then the uncompressed image buffer returned by the function will use the most optimal pixel format for the file type, and *pixelFormat will contain the ID of this pixel format upon successful return from the function. Otherwise, the uncompressed image buffer will use the pixel format specified in *pixelFormat, and pixel format conversion will be performed if necessary. If *pixelFormat is set to TJPF_CMYK, then the RGB or grayscale pixels stored in the file will be converted using a quick & dirty algorithm that is suitable only for testing purposes (proper conversion between CMYK and other formats requires a color management system.) |
+ | pixelFormat | pointer to an integer variable that specifies or will receive the pixel format of the uncompressed image buffer. The behavior of tjLoadImage() will vary depending on the value of *pixelFormat passed to the function:
+- TJPF_UNKNOWN : The uncompressed image buffer returned by the function will use the most optimal pixel format for the file type, and
*pixelFormat will contain the ID of this pixel format upon successful return from the function.
+- TJPF_GRAY : Only PGM files and 8-bit BMP files with a grayscale colormap can be loaded.
+- TJPF_CMYK : The RGB or grayscale pixels stored in the file will be converted using a quick & dirty algorithm that is suitable only for testing purposes (proper conversion between CMYK and other formats requires a color management system.)
+- Other pixel formats : The uncompressed image buffer will use the specified pixel format, and pixel format conversion will be performed if necessary.
+
+ |
| flags | the bitwise OR of one or more of the flags. |
diff --git a/rdbmp.c b/rdbmp.c
index 49616d01..44a62585 100644
--- a/rdbmp.c
+++ b/rdbmp.c
@@ -102,7 +102,7 @@ LOCAL(void)
read_colormap (bmp_source_ptr sinfo, int cmaplen, int mapentrysize)
/* Read the colormap from a BMP file */
{
- int i;
+ int i, gray = 1;
switch (mapentrysize) {
case 3:
@@ -111,6 +111,9 @@ read_colormap (bmp_source_ptr sinfo, int cmaplen, int mapentrysize)
sinfo->colormap[2][i] = (JSAMPLE) read_byte(sinfo);
sinfo->colormap[1][i] = (JSAMPLE) read_byte(sinfo);
sinfo->colormap[0][i] = (JSAMPLE) read_byte(sinfo);
+ if (sinfo->colormap[2][i] != sinfo->colormap[1][i] ||
+ sinfo->colormap[1][i] != sinfo->colormap[0][i])
+ gray = 0;
}
break;
case 4:
@@ -120,12 +123,18 @@ read_colormap (bmp_source_ptr sinfo, int cmaplen, int mapentrysize)
sinfo->colormap[1][i] = (JSAMPLE) read_byte(sinfo);
sinfo->colormap[0][i] = (JSAMPLE) read_byte(sinfo);
(void) read_byte(sinfo);
+ if (sinfo->colormap[2][i] != sinfo->colormap[1][i] ||
+ sinfo->colormap[1][i] != sinfo->colormap[0][i])
+ gray = 0;
}
break;
default:
ERREXIT(sinfo->cinfo, JERR_BMP_BADCMAP);
break;
}
+
+ if (sinfo->cinfo->in_color_space == JCS_GRAYSCALE && !gray)
+ ERREXIT(sinfo->cinfo, JERR_BAD_IN_COLORSPACE);
}
@@ -165,7 +174,7 @@ get_8bit_row (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
if (cinfo->in_color_space == JCS_GRAYSCALE) {
for (col = cinfo->image_width; col > 0; col--) {
t = GETJSAMPLE(*inptr++);
- *outptr++ = RGB2GRAY(colormap[0][t], colormap[1][t], colormap[2][t]);
+ *outptr++ = colormap[0][t];
}
} else if (cinfo->in_color_space == JCS_CMYK) {
for (col = cinfo->image_width; col > 0; col--) {
@@ -233,12 +242,6 @@ get_24bit_row (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
outptr = source->pub.buffer[0];
if (cinfo->in_color_space == JCS_EXT_BGR) {
MEMCOPY(outptr, inptr, source->row_width);
- } else if (cinfo->in_color_space == JCS_GRAYSCALE) {
- for (col = cinfo->image_width; col > 0; col--) {
- /* can omit GETJSAMPLE() safely */
- JSAMPLE b = *inptr++, g = *inptr++, r = *inptr++;
- *outptr++ = RGB2GRAY(r, g, b);
- }
} else if (cinfo->in_color_space == JCS_CMYK) {
for (col = cinfo->image_width; col > 0; col--) {
/* can omit GETJSAMPLE() safely */
@@ -304,12 +307,6 @@ get_32bit_row (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
if (cinfo->in_color_space == JCS_EXT_BGRX ||
cinfo->in_color_space == JCS_EXT_BGRA) {
MEMCOPY(outptr, inptr, source->row_width);
- } else if (cinfo->in_color_space == JCS_GRAYSCALE) {
- for (col = cinfo->image_width; col > 0; col--) {
- /* can omit GETJSAMPLE() safely */
- JSAMPLE b = *inptr++, g = *inptr++, r = *inptr++;
- *outptr++ = RGB2GRAY(r, g, b);
- }
} else if (cinfo->in_color_space == JCS_CMYK) {
for (col = cinfo->image_width; col > 0; col--) {
/* can omit GETJSAMPLE() safely */
@@ -554,16 +551,36 @@ start_input_bmp (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
case 8:
if (cinfo->in_color_space == JCS_UNKNOWN)
cinfo->in_color_space = JCS_EXT_RGB;
+ if (IsExtRGB(cinfo->in_color_space))
+ cinfo->input_components = rgb_pixelsize[cinfo->in_color_space];
+ else if (cinfo->in_color_space == JCS_GRAYSCALE)
+ cinfo->input_components = 1;
+ else if (cinfo->in_color_space == JCS_CMYK)
+ cinfo->input_components = 4;
+ else
+ ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE);
row_width = (JDIMENSION) biWidth;
break;
case 24:
if (cinfo->in_color_space == JCS_UNKNOWN)
cinfo->in_color_space = JCS_EXT_BGR;
+ if (IsExtRGB(cinfo->in_color_space))
+ cinfo->input_components = rgb_pixelsize[cinfo->in_color_space];
+ else if (cinfo->in_color_space == JCS_CMYK)
+ cinfo->input_components = 4;
+ else
+ ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE);
row_width = (JDIMENSION) (biWidth * 3);
break;
case 32:
if (cinfo->in_color_space == JCS_UNKNOWN)
cinfo->in_color_space = JCS_EXT_BGRA;
+ if (IsExtRGB(cinfo->in_color_space))
+ cinfo->input_components = rgb_pixelsize[cinfo->in_color_space];
+ else if (cinfo->in_color_space == JCS_CMYK)
+ cinfo->input_components = 4;
+ else
+ ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE);
row_width = (JDIMENSION) (biWidth * 4);
break;
default:
@@ -601,15 +618,6 @@ start_input_bmp (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
}
}
- if (IsExtRGB(cinfo->in_color_space))
- cinfo->input_components = rgb_pixelsize[cinfo->in_color_space];
- else if (cinfo->in_color_space == JCS_GRAYSCALE)
- cinfo->input_components = 1;
- else if (cinfo->in_color_space == JCS_CMYK)
- cinfo->input_components = 4;
- else
- ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE);
-
/* Allocate one-row buffer for returned data */
source->pub.buffer = (*cinfo->mem->alloc_sarray)
((j_common_ptr) cinfo, JPOOL_IMAGE,
diff --git a/rdppm.c b/rdppm.c
index 24987cf1..b7cd425c 100644
--- a/rdppm.c
+++ b/rdppm.c
@@ -277,38 +277,6 @@ get_text_rgb_row (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
}
-METHODDEF(JDIMENSION)
-get_text_rgb_gray_row (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
-/* This version is for reading text-format PPM files with any maxval and
- converting to grayscale */
-{
- ppm_source_ptr source = (ppm_source_ptr) sinfo;
- FILE *infile = source->pub.input_file;
- register JSAMPROW ptr;
- register JSAMPLE *rescale = source->rescale;
- JDIMENSION col;
- unsigned int maxval = source->maxval;
-
- ptr = source->pub.buffer[0];
- if (maxval == MAXJSAMPLE) {
- for (col = cinfo->image_width; col > 0; col--) {
- JSAMPLE r = read_pbm_integer(cinfo, infile, maxval);
- JSAMPLE g = read_pbm_integer(cinfo, infile, maxval);
- JSAMPLE b = read_pbm_integer(cinfo, infile, maxval);
- *ptr++ = RGB2GRAY(r, g, b);
- }
- } else {
- for (col = cinfo->image_width; col > 0; col--) {
- JSAMPLE r = rescale[read_pbm_integer(cinfo, infile, maxval)];
- JSAMPLE g = rescale[read_pbm_integer(cinfo, infile, maxval)];
- JSAMPLE b = rescale[read_pbm_integer(cinfo, infile, maxval)];
- *ptr++ = RGB2GRAY(r, g, b);
- }
- }
- return 1;
-}
-
-
METHODDEF(JDIMENSION)
get_text_rgb_cmyk_row (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
/* This version is for reading text-format PPM files with any maxval and
@@ -468,41 +436,6 @@ get_rgb_row (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
}
-METHODDEF(JDIMENSION)
-get_rgb_gray_row (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
-/* This version is for reading raw-byte-format PPM files with any maxval and
- converting to grayscale */
-{
- ppm_source_ptr source = (ppm_source_ptr) sinfo;
- register JSAMPROW ptr;
- register U_CHAR *bufferptr;
- register JSAMPLE *rescale = source->rescale;
- JDIMENSION col;
- unsigned int maxval = source->maxval;
-
- if (! ReadOK(source->pub.input_file, source->iobuffer, source->buffer_width))
- ERREXIT(cinfo, JERR_INPUT_EOF);
- ptr = source->pub.buffer[0];
- bufferptr = source->iobuffer;
- if (maxval == MAXJSAMPLE) {
- for (col = cinfo->image_width; col > 0; col--) {
- JSAMPLE r = *bufferptr++;
- JSAMPLE g = *bufferptr++;
- JSAMPLE b = *bufferptr++;
- *ptr++ = RGB2GRAY(r, g, b);
- }
- } else {
- for (col = cinfo->image_width; col > 0; col--) {
- JSAMPLE r = rescale[UCH(*bufferptr++)];
- JSAMPLE g = rescale[UCH(*bufferptr++)];
- JSAMPLE b = rescale[UCH(*bufferptr++)];
- *ptr++ = RGB2GRAY(r, g, b);
- }
- }
- return 1;
-}
-
-
METHODDEF(JDIMENSION)
get_rgb_cmyk_row (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
/* This version is for reading raw-byte-format PPM files with any maxval and
@@ -690,8 +623,6 @@ start_input_ppm (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
source->pub.get_pixel_rows = get_text_rgb_row;
else if (cinfo->in_color_space == JCS_CMYK)
source->pub.get_pixel_rows = get_text_rgb_cmyk_row;
- else if (cinfo->in_color_space == JCS_GRAYSCALE)
- source->pub.get_pixel_rows = get_text_rgb_gray_row;
else
ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE);
need_iobuffer = FALSE;
@@ -739,8 +670,6 @@ start_input_ppm (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
source->pub.get_pixel_rows = get_rgb_row;
else if (cinfo->in_color_space == JCS_CMYK)
source->pub.get_pixel_rows = get_rgb_cmyk_row;
- else if (cinfo->in_color_space == JCS_GRAYSCALE)
- source->pub.get_pixel_rows = get_rgb_gray_row;
else
ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE);
}
diff --git a/tjunittest.c b/tjunittest.c
index 4c1475aa..e723a4f3 100644
--- a/tjunittest.c
+++ b/tjunittest.c
@@ -69,9 +69,6 @@ void usage(char *progName)
bailout(); \
}
-#define RGB2GRAY(r, g, b) \
- (unsigned char)((double)(r)*0.299+(double)(g)*0.587+(double)(b)*0.114+0.5)
-
const char *subNameLong[TJ_NUMSAMP]=
{
"4:4:4", "4:2:2", "4:2:0", "GRAY", "4:4:0", "4:1:1"
@@ -717,7 +714,7 @@ void initBitmap(unsigned char *buf, int width, int pitch, int height, int pf,
unsigned char g=(j*256/height)%256;
unsigned char b=(j*256/height+i*256/width)%256;
memset(&buf[row*pitch+i*ps], 0, ps);
- if(pf==TJPF_GRAY) buf[row*pitch+i*ps]=RGB2GRAY(r, g, b);
+ if(pf==TJPF_GRAY) buf[row*pitch+i*ps]=b;
else if(pf==TJPF_CMYK)
rgb_to_cmyk(r, g, b, &buf[row*pitch+i*ps+0], &buf[row*pitch+i*ps+1],
&buf[row*pitch+i*ps+2], &buf[row*pitch+i*ps+3]);
@@ -752,7 +749,7 @@ int cmpBitmap(unsigned char *buf, int width, int pitch, int height, int pf,
unsigned char b=(j*256/height+i*256/width)%256;
if(pf==TJPF_GRAY)
{
- if(buf[row*pitch+i*ps]!=RGB2GRAY(r, g, b))
+ if(buf[row*pitch+i*ps]!=b)
return 0;
}
else if(pf==TJPF_CMYK)
@@ -763,8 +760,7 @@ int cmpBitmap(unsigned char *buf, int width, int pitch, int height, int pf,
&bf);
if(gray2rgb)
{
- unsigned char gray=RGB2GRAY(r, g, b);
- if(rf!=gray || gf!=gray || bf!=gray)
+ if(rf!=b || gf!=b || bf!=b)
return 0;
}
else if(rf!=r || gf!=g || bf!=b) return 0;
@@ -773,10 +769,9 @@ int cmpBitmap(unsigned char *buf, int width, int pitch, int height, int pf,
{
if(gray2rgb)
{
- unsigned char gray=RGB2GRAY(r, g, b);
- if(buf[row*pitch+i*ps+roffset]!=gray ||
- buf[row*pitch+i*ps+goffset]!=gray ||
- buf[row*pitch+i*ps+boffset]!=gray)
+ if(buf[row*pitch+i*ps+roffset]!=b ||
+ buf[row*pitch+i*ps+goffset]!=b ||
+ buf[row*pitch+i*ps+boffset]!=b)
return 0;
}
else if(buf[row*pitch+i*ps+roffset]!=r ||
@@ -803,8 +798,8 @@ int doBmpTest(const char *ext, int width, int align, int height, int pf,
if(pf==TJPF_GRAY)
{
- md5ref=!strcasecmp(ext, "ppm")? "bc77dea8eaf006aa187582b301f67e02":
- "2670a3f8cf19d855183c02ccf18d2a35";
+ md5ref=!strcasecmp(ext, "ppm")? "112c682e82ce5de1cca089e20d60000b":
+ "51976530acf75f02beddf5d21149101d";
}
else
{
@@ -863,20 +858,6 @@ int doBmpTest(const char *ext, int width, int align, int height, int pf,
retval=-1; goto bailout;
}
}
- else if(pf!=TJPF_CMYK)
- {
- tjFree(buf); buf=NULL;
- pf=TJPF_GRAY;
- if((buf=tjLoadImage(filename, &loadWidth, align, &loadHeight, &pf,
- flags))==NULL)
- _throwtj();
- pitch=PAD(width, align);
- if(!cmpBitmap(buf, width, pitch, height, pf, flags, 0))
- {
- printf("\n Converting %s to grayscale failed\n", filename);
- retval=-1; goto bailout;
- }
- }
unlink(filename);
bailout:
diff --git a/turbojpeg.h b/turbojpeg.h
index 7ffaf048..3a9c851c 100644
--- a/turbojpeg.h
+++ b/turbojpeg.h
@@ -1557,19 +1557,22 @@ DLLEXPORT unsigned char* DLLCALL tjAlloc(int bytes);
* (in pixels) of the uncompressed image
*
* @param pixelFormat pointer to an integer variable that specifies or will
- * receive the pixel format of the uncompressed image buffer. If
- * *pixelFormat is set to @ref TJPF_UNKNOWN prior to calling this
- * function, then the uncompressed image buffer returned by the function will
- * use the most optimal pixel format for the file type, and
+ * receive the pixel format of the uncompressed image buffer. The behavior of
+ * #tjLoadImage() will vary depending on the value of *pixelFormat
+ * passed to the function:
+ * - @ref TJPF_UNKNOWN : The uncompressed image buffer returned by the function
+ * will use the most optimal pixel format for the file type, and
* *pixelFormat will contain the ID of this pixel format upon
- * successful return from the function. Otherwise, the uncompressed image
- * buffer will use the @ref TJPF "pixel format" specified in
- * *pixelFormat, and pixel format conversion will be performed if
- * necessary. If *pixelFormat is set to @ref TJPF_CMYK, then the RGB
- * or grayscale pixels stored in the file will be converted using a quick &
- * dirty algorithm that is suitable only for testing purposes (proper
- * conversion between CMYK and other formats requires a color management
- * system.)
+ * successful return from the function.
+ * - @ref TJPF_GRAY : Only PGM files and 8-bit BMP files with a grayscale
+ * colormap can be loaded.
+ * - @ref TJPF_CMYK : The RGB or grayscale pixels stored in the file will be
+ * converted using a quick & dirty algorithm that is suitable only for testing
+ * purposes (proper conversion between CMYK and other formats requires a color
+ * management system.)
+ * - Other @ref TJPF "pixel formats" : The uncompressed image buffer will use
+ * the specified pixel format, and pixel format conversion will be performed if
+ * necessary.
*
* @param flags the bitwise OR of one or more of the @ref TJFLAG_BOTTOMUP
* "flags".