diff --git a/Makefile.am b/Makefile.am
index 6096049b..bd77c33d 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -196,14 +196,14 @@ MD5_JPEG_CROP = b4197f377e621c4e9b1d20471432610d
test: testclean all
if WITH_TURBOJPEG
-if WITH_JAVA
- $(JAVA) -cp java/turbojpeg.jar -Djava.library.path=.libs TJUnitTest
- $(JAVA) -cp java/turbojpeg.jar -Djava.library.path=.libs TJUnitTest -bi
- $(JAVA) -cp java/turbojpeg.jar -Djava.library.path=.libs TJUnitTest -yuv
- $(JAVA) -cp java/turbojpeg.jar -Djava.library.path=.libs TJUnitTest -yuv -noyuvpad
- $(JAVA) -cp java/turbojpeg.jar -Djava.library.path=.libs TJUnitTest -yuv -bi
- $(JAVA) -cp java/turbojpeg.jar -Djava.library.path=.libs TJUnitTest -yuv -bi -noyuvpad
-endif
+#if WITH_JAVA
+# $(JAVA) -cp java/turbojpeg.jar -Djava.library.path=.libs TJUnitTest
+# $(JAVA) -cp java/turbojpeg.jar -Djava.library.path=.libs TJUnitTest -bi
+# $(JAVA) -cp java/turbojpeg.jar -Djava.library.path=.libs TJUnitTest -yuv
+# $(JAVA) -cp java/turbojpeg.jar -Djava.library.path=.libs TJUnitTest -yuv -noyuvpad
+# $(JAVA) -cp java/turbojpeg.jar -Djava.library.path=.libs TJUnitTest -yuv -bi
+# $(JAVA) -cp java/turbojpeg.jar -Djava.library.path=.libs TJUnitTest -yuv -bi -noyuvpad
+#endif
./tjunittest
./tjunittest -alloc
./tjunittest -yuv
diff --git a/doc/html/group___turbo_j_p_e_g.html b/doc/html/group___turbo_j_p_e_g.html
index 26c7768b..92e1fe35 100644
--- a/doc/html/group___turbo_j_p_e_g.html
+++ b/doc/html/group___turbo_j_p_e_g.html
@@ -109,6 +109,9 @@ Macros
| #define | TJ_NUMPF |
| | The number of pixel formats. More...
|
| |
+| #define | TJ_NUMCS |
+| | The number of JPEG colorspaces. More...
|
+| |
| #define | TJFLAG_BOTTOMUP |
| | The uncompressed source/destination image is stored in bottom-up (Windows, OpenGL) order, not top-down (X11) order. More...
|
| |
@@ -197,11 +200,23 @@ Enumerations
TJPF_BGRA,
TJPF_ABGR,
-TJPF_ARGB
+TJPF_ARGB,
+TJPF_CMYK
}
| | Pixel formats. More...
|
| |
+| enum | TJCS {
+ TJCS_RGB,
+TJCS_YCbCr,
+TJCS_GRAY,
+TJCS_CMYK,
+
+ TJCS_YCCK
+
+ } |
+| | JPEG colorspaces. More...
|
+| |
| enum | TJXOP {
TJXOP_NONE,
TJXOP_HFLIP,
@@ -223,7 +238,7 @@ Functions |
| | Create a TurboJPEG compressor instance. More...
|
| |
| DLLEXPORT int DLLCALL | tjCompress2 (tjhandle handle, unsigned char *srcBuf, int width, int pitch, int height, int pixelFormat, unsigned char **jpegBuf, unsigned long *jpegSize, int jpegSubsamp, int jpegQual, int flags) |
-| | Compress an RGB or grayscale image into a JPEG image. More...
|
+| | Compress an RGB, grayscale, or CMYK image into a JPEG image. More...
|
| |
| DLLEXPORT unsigned long DLLCALL | tjBufSize (int width, int height, int jpegSubsamp) |
| | The maximum size of the buffer (in bytes) required to hold a JPEG image with the given parameters. More...
|
@@ -237,14 +252,14 @@ Functions
| DLLEXPORT tjhandle DLLCALL | tjInitDecompress (void) |
| | Create a TurboJPEG decompressor instance. More...
|
| |
-| DLLEXPORT int DLLCALL | tjDecompressHeader2 (tjhandle handle, unsigned char *jpegBuf, unsigned long jpegSize, int *width, int *height, int *jpegSubsamp) |
-| | Retrieve information about a JPEG image without decompressing it. More...
|
-| |
+| DLLEXPORT int DLLCALL | tjDecompressHeader3 (tjhandle handle, unsigned char *jpegBuf, unsigned long jpegSize, int *width, int *height, int *jpegSubsamp, int *jpegColorspace) |
+| | Retrieve information about a JPEG image without decompressing it. More...
|
+| |
| DLLEXPORT tjscalingfactor *DLLCALL | tjGetScalingFactors (int *numscalingfactors) |
| | Returns a list of fractional scaling factors that the JPEG decompressor in this implementation of TurboJPEG supports. More...
|
| |
| DLLEXPORT int DLLCALL | tjDecompress2 (tjhandle handle, unsigned char *jpegBuf, unsigned long jpegSize, unsigned char *dstBuf, int width, int pitch, int height, int pixelFormat, int flags) |
-| | Decompress a JPEG image to an RGB or grayscale image. More...
|
+| | Decompress a JPEG image to an RGB, grayscale, or CMYK image. More...
|
| |
| DLLEXPORT int DLLCALL | tjDecompressToYUV2 (tjhandle handle, unsigned char *jpegBuf, unsigned long jpegSize, unsigned char *dstBuf, int width, int pad, int height, int flags) |
| | Decompress a JPEG image to a YUV planar image. More...
|
@@ -293,6 +308,20 @@ Variables
TurboJPEG API.
This API provides an interface for generating, decoding, and transforming planar YUV and JPEG images in memory.
+
+
+
+
+
The number of JPEG colorspaces.
+
+
+
@@ -461,7 +490,7 @@ Variables
Disable buffer (re)allocation.
-
If passed to tjCompress2() or tjTransform(), this flag will cause those functions to generate an error if the JPEG image buffer is invalid or too small rather than attempting to allocate or reallocate that buffer. This reproduces the behavior of earlier versions of TurboJPEG.
+
If passed to tjCompress2() or tjTransform(), this flag will cause those functions to generate an error if the JPEG image buffer is invalid or too small rather than attempting to allocate or reallocate that buffer. This reproduces the behavior of earlier versions of TurboJPEG.
@@ -614,6 +643,42 @@ Variables
+
+
+
+
+
JPEG colorspaces.
+
+| Enumerator |
|---|
| TJCS_RGB |
+ RGB colorspace.
+When compressing the JPEG image, the R, G, and B components in the source image are reordered into image planes, but no colorspace conversion or subsampling is performed. RGB JPEG images can be decompressed to any of the extended RGB pixel formats or grayscale, but they cannot be decompressed to YUV images.
+ |
+| TJCS_YCbCr |
+ YCbCr colorspace.
+YCbCr is not an absolute colorspace but rather a mathematical transformation of RGB designed solely for storage and transmission. YCbCr images must be converted to RGB before they can actually be displayed. In the YCbCr colorspace, the Y (luminance) component represents the black & white portion of the original image, and the Cb and Cr (chrominance) components represent the color portion of the original image. Originally, the analog equivalent of this transformation allowed the same signal to drive both black & white and color televisions, but JPEG images use YCbCr primarily because it allows the color data to be optionally subsampled for the purposes of reducing bandwidth or disk space. YCbCr is the most common JPEG colorspace, and YCbCr JPEG images can be compressed from and decompressed to any of the extended RGB pixel formats or grayscale, or they can be decompressed to YUV planar images.
+ |
+| TJCS_GRAY |
+ Grayscale colorspace.
+The JPEG image retains only the luminance data (Y component), and any color data from the source image is discarded. Grayscale JPEG images can be compressed from and decompressed to any of the extended RGB pixel formats or grayscale, or they can be decompressed to YUV planar images.
+ |
+| TJCS_CMYK |
+ CMYK colorspace.
+When compressing the JPEG image, the C, M, Y, and K components in the source image are reordered into image planes, but no colorspace conversion or subsampling is performed. CMYK JPEG images can only be decompressed to CMYK pixels.
+ |
+| TJCS_YCCK |
+ YCCK colorspace.
+YCCK (AKA "YCbCrK") is not an absolute colorspace but rather a mathematical transformation of CMYK designed solely for storage and transmission. It is to CMYK as YCbCr is to RGB. CMYK pixels can be reversibly transformed into YCCK, and as with YCbCr, the chrominance components in the YCCK pixels can be subsampled without incurring major perceptual loss. YCCK JPEG images can only be compressed from and decompressed to CMYK pixels.
+ |
+
+
+
+
@@ -670,6 +735,10 @@ Variables
ARGB pixel format.
This is the same as TJPF_XRGB, except that when decompressing, the X component is guaranteed to be 0xFF, which can be interpreted as an opaque alpha channel.
+
| TJPF_CMYK |
+ CMYK pixel format.
+Unlike RGB, which is a display colorspace, CMYK (Cyan/Magenta/Yellow/Key) is a print colorspace in which the value of each color component corresponds to the amount of cyan, magenta, yellow, or black ink that is applied to a white background. In order to convert between CMYK and RGB, it is necessary to use a color management system (CMS.) A CMS will attempt to map colors within the printer's gamut to perceptually similar colors in the display's gamut and vice versa, but the mapping is typically not 1:1 or reversible, nor can it be defined with a simple formula. Thus, such a conversion is out of scope for a codec library. However, the TurboJPEG API allows for compressing CMYK pixels into a YCCK JPEG image (see TJCS_YCCK) and decompressing YCCK JPEG images into CMYK pixels.
+ |
@@ -685,7 +754,7 @@ Variables
Chrominance subsampling options.
-
When an image is converted from the RGB to the YUV colorspace as part of the JPEG compression process, some of the U and V (chrominance) components can be discarded or averaged together to produce a smaller image with little perceptible loss of image clarity (the human eye is more sensitive to small changes in brightness than small changes in color.) This is called "chrominance subsampling".
+
When pixels are converted from the RGB colorspace to YCbCr (see TJCS_YCbCr) or from the CMYK colorspace to YCCK (see TJCS_YCCK) as part of the JPEG compression process, some of the Cb and Cr (chrominance) components can be discarded or averaged together to produce a smaller image with little perceptible loss of image clarity (the human eye is more sensitive to small changes in brightness than small changes in color.) This is called "chrominance subsampling". (NOTE: In common usage, "YCbCr" and "YUV" have come to mean the same thing. The convention within the TurboJPEG API is to use "YUV" to refer to an image format consisting of Y, Cb, and Cr image planes, per the convention of the digital video community.)
| Enumerator |
|---|
| TJSAMP_444 |
4:4:4 chrominance subsampling (no chrominance subsampling).
@@ -776,7 +845,7 @@ Variables |
Allocate an image buffer for use with TurboJPEG.
-
You should always use this function to allocate the JPEG destination buffer(s) for tjCompress2() and tjTransform() unless you are disabling automatic buffer (re)allocation (by setting TJFLAG_NOREALLOC.)
+
You should always use this function to allocate the JPEG destination buffer(s) for tjCompress2() and tjTransform() unless you are disabling automatic buffer (re)allocation (by setting TJFLAG_NOREALLOC.)
- Parameters
-
| bytes | the number of bytes to allocate |
@@ -960,11 +1029,11 @@ Variables
-
Compress an RGB or grayscale image into a JPEG image.
+
Compress an RGB, grayscale, or CMYK image into a JPEG image.
- Parameters
-
| handle | a handle to a TurboJPEG compressor or transformer instance |
- | srcBuf | pointer to an image buffer containing RGB or grayscale pixels to be compressed |
+ | srcBuf | pointer to an image buffer containing RGB, grayscale, or CMYK pixels to be compressed |
| width | width (in pixels) of the source image |
| pitch | bytes per line of the source image. Normally, this should be width * tjPixelSize[pixelFormat] if the image is unpadded, or TJPAD(width * tjPixelSize[pixelFormat]) if each line of the image is padded to the nearest 32-bit boundary, as is the case for Windows bitmaps. You can also be clever and use this parameter to skip lines, etc. Setting this parameter to 0 is the equivalent of setting it to width * tjPixelSize[pixelFormat]. |
| height | height (in pixels) of the source image |
@@ -1052,7 +1121,7 @@ If you choose option 1, *jpegSize should be set to the size of your
-
Decompress a JPEG image to an RGB or grayscale image.
+
Decompress a JPEG image to an RGB, grayscale, or CMYK image.
- Parameters
-
| handle | a handle to a TurboJPEG decompressor or transformer instance |
@@ -1060,26 +1129,23 @@ If you choose option 1, *jpegSize should be set to the size of your
| jpegSize | size of the JPEG image (in bytes) |
| dstBuf | pointer to an image buffer that will receive the decompressed image. This buffer should normally be pitch * scaledHeight bytes in size, where scaledHeight can be determined by calling TJSCALED() with the JPEG image height and one of the scaling factors returned by tjGetScalingFactors(). The dstBuf pointer may also be used to decompress into a specific region of a larger buffer. |
| width | desired width (in pixels) of the destination image. If this is different than the width of the JPEG image being decompressed, then TurboJPEG will use scaling in the JPEG decompressor to generate the largest possible image that will fit within the desired width. If width is set to 0, then only the height will be considered when determining the scaled image size. |
- | pitch | bytes per line of the destination image. Normally, this is scaledWidth * tjPixelSize[pixelFormat] if the decompressed image is unpadded, else TJPAD(scaledWidth * tjPixelSize[pixelFormat]) if each line of the decompressed image is padded to the nearest 32-bit boundary, as is the case for Windows bitmaps. (NOTE: scaledWidth can be determined by calling TJSCALED() with the JPEG image width and one of the scaling factors returned by tjGetScalingFactors().) You can also be clever and use the pitch parameter to skip lines, etc. Setting this parameter to 0 is the equivalent of setting it to scaledWidth
- |
- | height | desired height (in pixels) of the destination image. If this is different than the height of the JPEG image being decompressed, then TurboJPEG will use scaling in the JPEG decompressor to generate the largest possible image that will fit within the desired height. If height is set to 0, then only the width will be considered when determining the scaled image size. |
- | pixelFormat | pixel format of the destination image (see Pixel formats.) |
- | flags | the bitwise OR of one or more of the flags. |
+ | pitch | bytes per line of the destination image. Normally, this is scaledWidth * tjPixelSize[pixelFormat] if the decompressed image is unpadded, else TJPAD(scaledWidth * tjPixelSize[pixelFormat]) if each line of the decompressed image is padded to the nearest 32-bit boundary, as is the case for Windows bitmaps. (NOTE: scaledWidth can be determined by calling TJSCALED() with the JPEG image width and one of the scaling factors returned by tjGetScalingFactors().) You can also be clever and use the pitch parameter to skip lines, etc. Setting this parameter to 0 is the equivalent of setting it to scaledWidth * tjPixelSize[pixelFormat]. |
+ | height | desired height (in pixels) of the destination image. If this is different than the height of the JPEG image being decompressed, then TurboJPEG will use scaling in the JPEG decompressor to generate the largest possible image that will fit within the desired height. If height is set to 0, then only the width will be considered when determining the scaled image size. |
+ | pixelFormat | pixel format of the destination image (see Pixel formats.) |
+ | flags | the bitwise OR of one or more of the flags. |
-
- Returns
0 if successful, or -1 if an error occurred (see tjGetErrorStr().)
+
- Returns
- 0 if successful, or -1 if an error occurred (see tjGetErrorStr().)
-
+
- | DLLEXPORT int DLLCALL tjDecompressHeader2 |
+ DLLEXPORT int DLLCALL tjDecompressHeader3 |
( |
tjhandle |
handle, |
@@ -1112,7 +1178,13 @@ If you choose option 1, *jpegSize should be set to the size of your
|
|
int * |
- jpegSubsamp |
+ jpegSubsamp, |
+
+
+ |
+ |
+ int * |
+ jpegColorspace |
|
@@ -1130,7 +1202,8 @@ If you choose option 1, *jpegSize should be set to the size of your
| jpegSize | size of the JPEG image (in bytes) |
| width | pointer to an integer variable that will receive the width (in pixels) of the JPEG image |
| height | pointer to an integer variable that will receive the height (in pixels) of the JPEG image |
- | jpegSubsamp | pointer to an integer variable that will receive the level of chrominance subsampling used when compressing the JPEG image (see Chrominance subsampling options.) |
+ | jpegSubsamp | pointer to an integer variable that will receive the level of chrominance subsampling used when compressing the JPEG image (see Chrominance subsampling options.) |
+ | jpegColorspace | pointer to an integer variable that will receive one of the JPEG colorspace constants, indicating the colorspace of the JPEG image (see JPEG colorspaces.) |
@@ -1350,7 +1423,7 @@ If you choose option 1,
*jpegSize should be set to the size of your
Free an image buffer previously allocated by TurboJPEG.
-
You should always use this function to free JPEG destination buffer(s) that were automatically (re)allocated by tjCompress2() or tjTransform() or that were manually allocated using tjAlloc().
+
You should always use this function to free JPEG destination buffer(s) that were automatically (re)allocated by tjCompress2() or tjTransform() or that were manually allocated using tjAlloc().
- Parameters
-
| buffer | address of the buffer to free |
diff --git a/doc/html/search/all_74.js b/doc/html/search/all_74.js
index 01c414a9..4aec5286 100644
--- a/doc/html/search/all_74.js
+++ b/doc/html/search/all_74.js
@@ -1,5 +1,6 @@
var searchData=
[
+ ['tj_5fnumcs',['TJ_NUMCS',['../group___turbo_j_p_e_g.html#ga39f57a6fb02d9cf32e7b6890099b5a71',1,'turbojpeg.h']]],
['tj_5fnumpf',['TJ_NUMPF',['../group___turbo_j_p_e_g.html#ga7010a4402f54a45ba822ad8675a4655e',1,'turbojpeg.h']]],
['tj_5fnumsamp',['TJ_NUMSAMP',['../group___turbo_j_p_e_g.html#ga5ef3d169162ce77ce348e292a0b7477c',1,'turbojpeg.h']]],
['tj_5fnumxop',['TJ_NUMXOP',['../group___turbo_j_p_e_g.html#ga0f6dbd18adf38b7d46ac547f0f4d562c',1,'turbojpeg.h']]],
@@ -8,8 +9,14 @@ var searchData=
['tjbufsize',['tjBufSize',['../group___turbo_j_p_e_g.html#gaccc5bca7f12fcdcc302e6e1c6d4b311b',1,'turbojpeg.h']]],
['tjbufsizeyuv2',['tjBufSizeYUV2',['../group___turbo_j_p_e_g.html#gaf451664a62c1f6c7cc5a6401f32908c9',1,'turbojpeg.h']]],
['tjcompress2',['tjCompress2',['../group___turbo_j_p_e_g.html#gaba62b7a98f960839b588579898495cf2',1,'turbojpeg.h']]],
+ ['tjcs',['TJCS',['../group___turbo_j_p_e_g.html#ga4f83ad3368e0e29d1957be0efa7c3720',1,'turbojpeg.h']]],
+ ['tjcs_5fcmyk',['TJCS_CMYK',['../group___turbo_j_p_e_g.html#gga4f83ad3368e0e29d1957be0efa7c3720a6c8b636152ac8195b869587db315ee53',1,'turbojpeg.h']]],
+ ['tjcs_5fgray',['TJCS_GRAY',['../group___turbo_j_p_e_g.html#gga4f83ad3368e0e29d1957be0efa7c3720ab3e7d6a87f695e45b81c1b5262b5a50a',1,'turbojpeg.h']]],
+ ['tjcs_5frgb',['TJCS_RGB',['../group___turbo_j_p_e_g.html#gga4f83ad3368e0e29d1957be0efa7c3720a677cb7ccb85c4038ac41964a2e09e555',1,'turbojpeg.h']]],
+ ['tjcs_5fycbcr',['TJCS_YCbCr',['../group___turbo_j_p_e_g.html#gga4f83ad3368e0e29d1957be0efa7c3720a7389b8f65bb387ffedce3efd0d78ec75',1,'turbojpeg.h']]],
+ ['tjcs_5fycck',['TJCS_YCCK',['../group___turbo_j_p_e_g.html#gga4f83ad3368e0e29d1957be0efa7c3720a53839e0fe867b76b58d16b0a1a7c598e',1,'turbojpeg.h']]],
['tjdecompress2',['tjDecompress2',['../group___turbo_j_p_e_g.html#gada69cc6443d1bb493b40f1626259e5e9',1,'turbojpeg.h']]],
- ['tjdecompressheader2',['tjDecompressHeader2',['../group___turbo_j_p_e_g.html#gac5675fceb7997b385516cdffdb34e6aa',1,'turbojpeg.h']]],
+ ['tjdecompressheader3',['tjDecompressHeader3',['../group___turbo_j_p_e_g.html#gacd0fac3af74b3511d39b4781b7103086',1,'turbojpeg.h']]],
['tjdecompresstoyuv2',['tjDecompressToYUV2',['../group___turbo_j_p_e_g.html#ga7c08b340ad7f8e85d407bd9e81d44d07',1,'turbojpeg.h']]],
['tjdestroy',['tjDestroy',['../group___turbo_j_p_e_g.html#ga674adee917b95ad4a896f1ba39e12540',1,'turbojpeg.h']]],
['tjencodeyuv3',['tjEncodeYUV3',['../group___turbo_j_p_e_g.html#ga0a5ffbf7cb58a5b6a8201114fe889360',1,'turbojpeg.h']]],
@@ -39,6 +46,7 @@ var searchData=
['tjpf_5fbgr',['TJPF_BGR',['../group___turbo_j_p_e_g.html#ggac916144e26c3817ac514e64ae5d12e2aab10624437fb8ef495a0b153e65749839',1,'turbojpeg.h']]],
['tjpf_5fbgra',['TJPF_BGRA',['../group___turbo_j_p_e_g.html#ggac916144e26c3817ac514e64ae5d12e2aac037ff1845cf9b74bb81a3659c2b9fb4',1,'turbojpeg.h']]],
['tjpf_5fbgrx',['TJPF_BGRX',['../group___turbo_j_p_e_g.html#ggac916144e26c3817ac514e64ae5d12e2aa2a1fbf569ca79897eae886e3376ca4c8',1,'turbojpeg.h']]],
+ ['tjpf_5fcmyk',['TJPF_CMYK',['../group___turbo_j_p_e_g.html#ggac916144e26c3817ac514e64ae5d12e2aa7f5100ec44c91994e243f1cf55553f8b',1,'turbojpeg.h']]],
['tjpf_5fgray',['TJPF_GRAY',['../group___turbo_j_p_e_g.html#ggac916144e26c3817ac514e64ae5d12e2aa5431b54b015337705f13118073711a1a',1,'turbojpeg.h']]],
['tjpf_5frgb',['TJPF_RGB',['../group___turbo_j_p_e_g.html#ggac916144e26c3817ac514e64ae5d12e2aa7ce93230bff449518ce387c17e6ed37c',1,'turbojpeg.h']]],
['tjpf_5frgba',['TJPF_RGBA',['../group___turbo_j_p_e_g.html#ggac916144e26c3817ac514e64ae5d12e2aa88d2e88fab67f6503cf972e14851cc12',1,'turbojpeg.h']]],
diff --git a/doc/html/search/enums_74.js b/doc/html/search/enums_74.js
index 20bd4db4..276aa241 100644
--- a/doc/html/search/enums_74.js
+++ b/doc/html/search/enums_74.js
@@ -1,5 +1,6 @@
var searchData=
[
+ ['tjcs',['TJCS',['../group___turbo_j_p_e_g.html#ga4f83ad3368e0e29d1957be0efa7c3720',1,'turbojpeg.h']]],
['tjpf',['TJPF',['../group___turbo_j_p_e_g.html#gac916144e26c3817ac514e64ae5d12e2a',1,'turbojpeg.h']]],
['tjsamp',['TJSAMP',['../group___turbo_j_p_e_g.html#ga1d047060ea80bb9820d540bb928e9074',1,'turbojpeg.h']]],
['tjxop',['TJXOP',['../group___turbo_j_p_e_g.html#ga2de531af4e7e6c4f124908376b354866',1,'turbojpeg.h']]]
diff --git a/doc/html/search/enumvalues_74.js b/doc/html/search/enumvalues_74.js
index 16e7e15f..7dc2f8dc 100644
--- a/doc/html/search/enumvalues_74.js
+++ b/doc/html/search/enumvalues_74.js
@@ -1,10 +1,16 @@
var searchData=
[
+ ['tjcs_5fcmyk',['TJCS_CMYK',['../group___turbo_j_p_e_g.html#gga4f83ad3368e0e29d1957be0efa7c3720a6c8b636152ac8195b869587db315ee53',1,'turbojpeg.h']]],
+ ['tjcs_5fgray',['TJCS_GRAY',['../group___turbo_j_p_e_g.html#gga4f83ad3368e0e29d1957be0efa7c3720ab3e7d6a87f695e45b81c1b5262b5a50a',1,'turbojpeg.h']]],
+ ['tjcs_5frgb',['TJCS_RGB',['../group___turbo_j_p_e_g.html#gga4f83ad3368e0e29d1957be0efa7c3720a677cb7ccb85c4038ac41964a2e09e555',1,'turbojpeg.h']]],
+ ['tjcs_5fycbcr',['TJCS_YCbCr',['../group___turbo_j_p_e_g.html#gga4f83ad3368e0e29d1957be0efa7c3720a7389b8f65bb387ffedce3efd0d78ec75',1,'turbojpeg.h']]],
+ ['tjcs_5fycck',['TJCS_YCCK',['../group___turbo_j_p_e_g.html#gga4f83ad3368e0e29d1957be0efa7c3720a53839e0fe867b76b58d16b0a1a7c598e',1,'turbojpeg.h']]],
['tjpf_5fabgr',['TJPF_ABGR',['../group___turbo_j_p_e_g.html#ggac916144e26c3817ac514e64ae5d12e2aa1ba1a7f1631dbeaa49a0a85fc4a40081',1,'turbojpeg.h']]],
['tjpf_5fargb',['TJPF_ARGB',['../group___turbo_j_p_e_g.html#ggac916144e26c3817ac514e64ae5d12e2aae8f846ed9d9de99b6e1dfe448848765c',1,'turbojpeg.h']]],
['tjpf_5fbgr',['TJPF_BGR',['../group___turbo_j_p_e_g.html#ggac916144e26c3817ac514e64ae5d12e2aab10624437fb8ef495a0b153e65749839',1,'turbojpeg.h']]],
['tjpf_5fbgra',['TJPF_BGRA',['../group___turbo_j_p_e_g.html#ggac916144e26c3817ac514e64ae5d12e2aac037ff1845cf9b74bb81a3659c2b9fb4',1,'turbojpeg.h']]],
['tjpf_5fbgrx',['TJPF_BGRX',['../group___turbo_j_p_e_g.html#ggac916144e26c3817ac514e64ae5d12e2aa2a1fbf569ca79897eae886e3376ca4c8',1,'turbojpeg.h']]],
+ ['tjpf_5fcmyk',['TJPF_CMYK',['../group___turbo_j_p_e_g.html#ggac916144e26c3817ac514e64ae5d12e2aa7f5100ec44c91994e243f1cf55553f8b',1,'turbojpeg.h']]],
['tjpf_5fgray',['TJPF_GRAY',['../group___turbo_j_p_e_g.html#ggac916144e26c3817ac514e64ae5d12e2aa5431b54b015337705f13118073711a1a',1,'turbojpeg.h']]],
['tjpf_5frgb',['TJPF_RGB',['../group___turbo_j_p_e_g.html#ggac916144e26c3817ac514e64ae5d12e2aa7ce93230bff449518ce387c17e6ed37c',1,'turbojpeg.h']]],
['tjpf_5frgba',['TJPF_RGBA',['../group___turbo_j_p_e_g.html#ggac916144e26c3817ac514e64ae5d12e2aa88d2e88fab67f6503cf972e14851cc12',1,'turbojpeg.h']]],
diff --git a/doc/html/search/functions_74.js b/doc/html/search/functions_74.js
index cedfc7af..8f92c26d 100644
--- a/doc/html/search/functions_74.js
+++ b/doc/html/search/functions_74.js
@@ -5,7 +5,7 @@ var searchData=
['tjbufsizeyuv2',['tjBufSizeYUV2',['../group___turbo_j_p_e_g.html#gaf451664a62c1f6c7cc5a6401f32908c9',1,'turbojpeg.h']]],
['tjcompress2',['tjCompress2',['../group___turbo_j_p_e_g.html#gaba62b7a98f960839b588579898495cf2',1,'turbojpeg.h']]],
['tjdecompress2',['tjDecompress2',['../group___turbo_j_p_e_g.html#gada69cc6443d1bb493b40f1626259e5e9',1,'turbojpeg.h']]],
- ['tjdecompressheader2',['tjDecompressHeader2',['../group___turbo_j_p_e_g.html#gac5675fceb7997b385516cdffdb34e6aa',1,'turbojpeg.h']]],
+ ['tjdecompressheader3',['tjDecompressHeader3',['../group___turbo_j_p_e_g.html#gacd0fac3af74b3511d39b4781b7103086',1,'turbojpeg.h']]],
['tjdecompresstoyuv2',['tjDecompressToYUV2',['../group___turbo_j_p_e_g.html#ga7c08b340ad7f8e85d407bd9e81d44d07',1,'turbojpeg.h']]],
['tjdestroy',['tjDestroy',['../group___turbo_j_p_e_g.html#ga674adee917b95ad4a896f1ba39e12540',1,'turbojpeg.h']]],
['tjencodeyuv3',['tjEncodeYUV3',['../group___turbo_j_p_e_g.html#ga0a5ffbf7cb58a5b6a8201114fe889360',1,'turbojpeg.h']]],
diff --git a/doc/html/structtjtransform.html b/doc/html/structtjtransform.html
index 33e37245..9f2939a3 100644
--- a/doc/html/structtjtransform.html
+++ b/doc/html/structtjtransform.html
@@ -108,7 +108,7 @@ Data Fields
| | Arbitrary data that can be accessed within the body of the callback function. More...
|
| |
| int(* | customFilter )(short *coeffs, tjregion arrayRegion, tjregion planeRegion, int componentIndex, int transformIndex, struct tjtransform *transform) |
-| | A callback function that can be used to modify the DCT coefficients after they are losslessly transformed but before they are transcoded to a new JPEG file. More...
|
+| | A callback function that can be used to modify the DCT coefficients after they are losslessly transformed but before they are transcoded to a new JPEG image. More...
|
| |
@@ -124,7 +124,7 @@ Data Fields
-
A callback function that can be used to modify the DCT coefficients after they are losslessly transformed but before they are transcoded to a new JPEG file.
+
A callback function that can be used to modify the DCT coefficients after they are losslessly transformed but before they are transcoded to a new JPEG image.
This allows for custom filters or other transformations to be applied in the frequency domain.
- Parameters
-
diff --git a/tjbench.c b/tjbench.c
index 10a0f266..615f2f73 100644
--- a/tjbench.c
+++ b/tjbench.c
@@ -56,6 +56,10 @@ const char *subNameLong[TJ_NUMSAMP]=
{
"4:4:4", "4:2:2", "4:2:0", "GRAY", "4:4:0", "4:1:1"
};
+const char *csName[TJ_NUMCS]=
+{
+ "RGB", "YCbCr", "GRAY", "CMYK", "YCCK"
+};
const char *subName[TJ_NUMSAMP]={"444", "422", "420", "GRAY", "440", "411"};
tjscalingfactor *scalingfactors=NULL, sf={1, 1}; int nsf=0;
int xformop=TJXOP_NONE, xformopt=0;
@@ -63,6 +67,18 @@ int (*customFilter)(short *, tjregion, tjregion, int, int, tjtransform *);
double benchtime=5.0;
+char *formatName(int subsamp, int cs, char *buf)
+{
+ if(cs==TJCS_YCbCr) return subNameLong[subsamp];
+ else if(cs==TJCS_YCCK)
+ {
+ snprintf(buf, 80, "%s %s", csName[cs], subNameLong[subsamp]);
+ return buf;
+ }
+ else return csName[cs];
+}
+
+
char *sigfig(double val, int figs, char *buf, int len)
{
char format[80];
@@ -466,7 +482,7 @@ void dodecomptest(char *filename)
unsigned char **jpegbuf=NULL, *srcbuf=NULL;
unsigned long *jpegsize=NULL, srcsize, totaljpegsize;
tjtransform *t=NULL;
- int w=0, h=0, subsamp=-1, _w, _h, _tilew, _tileh,
+ int w=0, h=0, subsamp=-1, cs=-1, _w, _h, _tilew, _tileh,
_ntilesw, _ntilesh, _subsamp;
char *temp=NULL, tempstr[80], tempstr2[80];
int row, col, i, tilew, tileh, ntilesw=1, ntilesh=1, retval=0;
@@ -490,20 +506,25 @@ void dodecomptest(char *filename)
if((handle=tjInitTransform())==NULL)
_throwtj("executing tjInitTransform()");
- if(tjDecompressHeader2(handle, srcbuf, srcsize, &w, &h, &subsamp)==-1)
- _throwtj("executing tjDecompressHeader2()");
+ if(tjDecompressHeader3(handle, srcbuf, srcsize, &w, &h, &subsamp, &cs)==-1)
+ _throwtj("executing tjDecompressHeader3()");
if(quiet==1)
{
printf("All performance values in Mpixels/sec\n\n");
- printf("Bitmap\tBitmap\tJPEG\t%s %s \tXform\tComp\tDecomp\n",
+ printf("Bitmap\tBitmap\tJPEG\tJPEG\t%s %s \tXform\tComp\tDecomp\n",
dotile? "Tile ":"Image", dotile? "Tile ":"Image");
- printf("Format\tOrder\tSubsamp\tWidth Height\tPerf \tRatio\tPerf\n\n");
+ printf("Format\tOrder\tCS\tSubsamp\tWidth Height\tPerf \tRatio\tPerf\n\n");
}
else if(!quiet)
{
- printf(">>>>> JPEG %s --> %s (%s) <<<<<\n", subNameLong[subsamp],
- pixFormatStr[pf], (flags&TJFLAG_BOTTOMUP)? "Bottom-up":"Top-down");
+ if(yuv==YUVDECODE)
+ printf(">>>>> JPEG %s --> YUV <<<<<\n",
+ formatName(subsamp, cs, tempstr));
+ else
+ printf(">>>>> JPEG %s --> %s (%s) <<<<<\n",
+ formatName(subsamp, cs, tempstr), pixFormatStr[pf],
+ (flags&TJFLAG_BOTTOMUP)? "Bottom-up":"Top-down");
}
for(tilew=dotile? 16:w, tileh=dotile? 16:h; ; tilew*=2, tileh*=2)
@@ -539,8 +560,8 @@ void dodecomptest(char *filename)
}
else if(quiet==1)
{
- printf("%s\t%s\t%s\t", pixFormatStr[pf],
- (flags&TJFLAG_BOTTOMUP)? "BU":"TD", subNameLong[subsamp]);
+ printf("%s\t%s\t%s\t%s\t", pixFormatStr[pf],
+ (flags&TJFLAG_BOTTOMUP)? "BU":"TD", csName[cs], subNameLong[subsamp]);
printf("%-4d %-4d\t", tilew, tileh);
}
diff --git a/tjunittest.c b/tjunittest.c
index 29ed90da..16ecd093 100644
--- a/tjunittest.c
+++ b/tjunittest.c
@@ -68,13 +68,14 @@ const char *subName[TJ_NUMSAMP]={"444", "422", "420", "GRAY", "440", "411"};
const char *pixFormatStr[TJ_NUMPF]=
{
"RGB", "BGR", "RGBX", "BGRX", "XBGR", "XRGB", "Grayscale",
- "RGBA", "BGRA", "ABGR", "ARGB"
+ "RGBA", "BGRA", "ABGR", "ARGB", "CMYK"
};
-const int alphaOffset[TJ_NUMPF] = {-1, -1, -1, -1, -1, -1, -1, 3, 3, 0, 0};
+const int alphaOffset[TJ_NUMPF] = {-1, -1, -1, -1, -1, -1, -1, 3, 3, 0, 0, -1};
const int _3byteFormats[]={TJPF_RGB, TJPF_BGR};
-const int _4byteFormats[]={TJPF_RGBX, TJPF_BGRX, TJPF_XBGR, TJPF_XRGB};
+const int _4byteFormats[]={TJPF_RGBX, TJPF_BGRX, TJPF_XBGR, TJPF_XRGB,
+ TJPF_CMYK};
const int _onlyGray[]={TJPF_GRAY};
const int _onlyRGB[]={TJPF_RGB};
@@ -93,9 +94,9 @@ void initBuf(unsigned char *buf, int w, int h, int pf, int flags)
int ps=tjPixelSize[pf];
int index, row, col, halfway=16;
- memset(buf, 0, w*h*ps);
if(pf==TJPF_GRAY)
{
+ memset(buf, 0, w*h*ps);
for(row=0; row=halfway) buf[index*ps+3]=0;
+ }
+ else
+ {
+ buf[index*ps+2]=0;
+ if(rowin_color_space=JCS_RGB; pixelFormat=TJPF_RGB;
break;
#endif
+ case TJPF_CMYK:
+ cinfo->in_color_space=JCS_CMYK; break;
}
cinfo->input_components=tjPixelSize[pixelFormat];
@@ -199,15 +201,20 @@ static int setCompDefaults(struct jpeg_compress_struct *cinfo,
}
if(subsamp==TJSAMP_GRAY)
jpeg_set_colorspace(cinfo, JCS_GRAYSCALE);
- else
- jpeg_set_colorspace(cinfo, JCS_YCbCr);
+ else if(pixelFormat==TJPF_CMYK)
+ jpeg_set_colorspace(cinfo, JCS_YCCK);
+ else jpeg_set_colorspace(cinfo, JCS_YCbCr);
cinfo->comp_info[0].h_samp_factor=tjMCUWidth[subsamp]/8;
cinfo->comp_info[1].h_samp_factor=1;
cinfo->comp_info[2].h_samp_factor=1;
+ if(cinfo->num_components>3)
+ cinfo->comp_info[3].h_samp_factor=tjMCUWidth[subsamp]/8;
cinfo->comp_info[0].v_samp_factor=tjMCUHeight[subsamp]/8;
cinfo->comp_info[1].v_samp_factor=1;
cinfo->comp_info[2].v_samp_factor=1;
+ if(cinfo->num_components>3)
+ cinfo->comp_info[3].v_samp_factor=tjMCUHeight[subsamp]/8;
return retval;
}
@@ -257,6 +264,8 @@ static int setDecompDefaults(struct jpeg_decompress_struct *dinfo,
case TJPF_ABGR:
dinfo->out_color_space=JCS_RGB; break;
#endif
+ case TJPF_CMYK:
+ dinfo->out_color_space=JCS_CMYK; break;
default:
_throw("Unsupported pixel format");
}
@@ -273,7 +282,10 @@ static int getSubsamp(j_decompress_ptr dinfo)
int retval=-1, i, k;
for(i=0; inum_components==pixelsize[i])
+ if(dinfo->num_components==pixelsize[i]
+ || ((dinfo->jpeg_color_space==JCS_YCCK
+ || dinfo->jpeg_color_space==JCS_CMYK)
+ && pixelsize[i]==3 && dinfo->num_components==4))
{
if(dinfo->comp_info[0].h_samp_factor==tjMCUWidth[i]/8
&& dinfo->comp_info[0].v_samp_factor==tjMCUHeight[i]/8)
@@ -281,8 +293,13 @@ static int getSubsamp(j_decompress_ptr dinfo)
int match=0;
for(k=1; knum_components; k++)
{
- if(dinfo->comp_info[k].h_samp_factor==1
- && dinfo->comp_info[k].v_samp_factor==1)
+ int href=1, vref=1;
+ if(dinfo->jpeg_color_space==JCS_YCCK && k==3)
+ {
+ href=tjMCUWidth[i]/8; vref=tjMCUHeight[i]/8;
+ }
+ if(dinfo->comp_info[k].h_samp_factor==href
+ && dinfo->comp_info[k].v_samp_factor==vref)
match++;
}
if(match==dinfo->num_components-1)
@@ -715,6 +732,9 @@ DLLEXPORT int DLLCALL tjEncodeYUV3(tjhandle handle, unsigned char *srcBuf,
goto bailout;
}
+ if(pixelFormat==TJPF_CMYK)
+ _throw("tjEncodeYUV3(): Cannot generate YUV images from CMYK pixels");
+
if(pitch==0) pitch=width*tjPixelSize[pixelFormat];
#ifndef JCS_EXTENSIONS
@@ -880,19 +900,19 @@ DLLEXPORT tjhandle DLLCALL tjInitDecompress(void)
}
-DLLEXPORT int DLLCALL tjDecompressHeader2(tjhandle handle,
+DLLEXPORT int DLLCALL tjDecompressHeader3(tjhandle handle,
unsigned char *jpegBuf, unsigned long jpegSize, int *width, int *height,
- int *jpegSubsamp)
+ int *jpegSubsamp, int *jpegColorspace)
{
int retval=0;
getinstance(handle);
if((this->init&DECOMPRESS)==0)
- _throw("tjDecompressHeader2(): Instance has not been initialized for decompression");
+ _throw("tjDecompressHeader3(): Instance has not been initialized for decompression");
if(jpegBuf==NULL || jpegSize<=0 || width==NULL || height==NULL
- || jpegSubsamp==NULL)
- _throw("tjDecompressHeader2(): Invalid argument");
+ || jpegSubsamp==NULL || jpegColorspace==NULL)
+ _throw("tjDecompressHeader3(): Invalid argument");
if(setjmp(this->jerr.setjmp_buffer))
{
@@ -906,18 +926,38 @@ DLLEXPORT int DLLCALL tjDecompressHeader2(tjhandle handle,
*width=dinfo->image_width;
*height=dinfo->image_height;
*jpegSubsamp=getSubsamp(dinfo);
+ switch(dinfo->jpeg_color_space)
+ {
+ case JCS_GRAYSCALE: *jpegColorspace=TJCS_GRAY; break;
+ case JCS_RGB: *jpegColorspace=TJCS_RGB; break;
+ case JCS_YCbCr: *jpegColorspace=TJCS_YCbCr; break;
+ case JCS_CMYK: *jpegColorspace=TJCS_CMYK; break;
+ case JCS_YCCK: *jpegColorspace=TJCS_YCCK; break;
+ default: *jpegColorspace=-1; break;
+ }
jpeg_abort_decompress(dinfo);
if(*jpegSubsamp<0)
- _throw("tjDecompressHeader2(): Could not determine subsampling type for JPEG image");
+ _throw("tjDecompressHeader3(): Could not determine subsampling type for JPEG image");
+ if(*jpegColorspace<0)
+ _throw("tjDecompressHeader3(): Could not determine colorspace of JPEG image");
if(*width<1 || *height<1)
- _throw("tjDecompressHeader2(): Invalid data returned in header");
+ _throw("tjDecompressHeader3(): Invalid data returned in header");
bailout:
return retval;
}
+DLLEXPORT int DLLCALL tjDecompressHeader2(tjhandle handle,
+ unsigned char *jpegBuf, unsigned long jpegSize, int *width, int *height,
+ int *jpegSubsamp)
+{
+ int jpegColorspace;
+ return tjDecompressHeader3(handle, jpegBuf, jpegSize, width, height,
+ jpegSubsamp, &jpegColorspace);
+}
+
DLLEXPORT int DLLCALL tjDecompressHeader(tjhandle handle,
unsigned char *jpegBuf, unsigned long jpegSize, int *width, int *height)
{
@@ -1107,6 +1147,9 @@ DLLEXPORT int DLLCALL tjDecompressToYUV2(tjhandle handle,
}
if(scaledw>width || scaledh>height)
_throw("tjDecompressToYUV2(): Could not scale down to desired image dimensions");
+ if(dinfo->num_components>3)
+ _throw("tjDecompressToYUV2(): JPEG image must have 3 or fewer components");
+
width=scaledw; height=scaledh;
dinfo->scale_num=sf[i].num;
dinfo->scale_denom=sf[i].denom;
diff --git a/turbojpeg.h b/turbojpeg.h
index 668a50a6..d0981439 100644
--- a/turbojpeg.h
+++ b/turbojpeg.h
@@ -53,12 +53,16 @@
/**
* Chrominance subsampling options.
- * When an image is converted from the RGB to the YUV colorspace as part of
- * the JPEG compression process, some of the U and V (chrominance) components
- * can be discarded or averaged together to produce a smaller image with little
+ * When pixels are converted from the RGB colorspace to YCbCr (see #TJCS_YCbCr)
+ * or from the CMYK colorspace to YCCK (see #TJCS_YCCK) as part of the JPEG
+ * compression process, some of the Cb and Cr (chrominance) components can be
+ * discarded or averaged together to produce a smaller image with little
* perceptible loss of image clarity (the human eye is more sensitive to small
* changes in brightness than small changes in color.) This is called
- * "chrominance subsampling".
+ * "chrominance subsampling". (NOTE: In common usage, "YCbCr" and "YUV" have
+ * come to mean the same thing. The convention within the TurboJPEG API is to
+ * use "YUV" to refer to an image format consisting of Y, Cb, and Cr image
+ * planes, per the convention of the digital video community.)
*/
enum TJSAMP
{
@@ -127,7 +131,7 @@ static const int tjMCUHeight[TJ_NUMSAMP] = {8, 8, 16, 8, 16, 8};
/**
* The number of pixel formats
*/
-#define TJ_NUMPF 11
+#define TJ_NUMPF 12
/**
* Pixel formats
@@ -202,16 +206,94 @@ enum TJPF
* decompressing, the X component is guaranteed to be 0xFF, which can be
* interpreted as an opaque alpha channel.
*/
- TJPF_ARGB
+ TJPF_ARGB,
+ /**
+ * CMYK pixel format. Unlike RGB, which is a display colorspace,
+ * CMYK (Cyan/Magenta/Yellow/Key) is a print colorspace in which the
+ * value of each color component corresponds to the amount of cyan, magenta,
+ * yellow, or black ink that is applied to a white background. In order to
+ * convert between CMYK and RGB, it is necessary to use a color management
+ * system (CMS.) A CMS will attempt to map colors within the printer's gamut
+ * to perceptually similar colors in the display's gamut and vice versa, but
+ * the mapping is typically not 1:1 or reversible, nor can it be defined with
+ * a simple formula. Thus, such a conversion is out of scope for a codec
+ * library. However, the TurboJPEG API allows for compressing CMYK pixels
+ * into a YCCK JPEG image (see #TJCS_YCCK) and decompressing YCCK JPEG images
+ * into CMYK pixels.
+ */
+ TJPF_CMYK
};
+
+/**
+ * The number of JPEG colorspaces
+ */
+#define TJ_NUMCS 12
+
+/**
+ * JPEG colorspaces
+ */
+enum TJCS
+{
+ /**
+ * RGB colorspace. When compressing the JPEG image, the R, G, and B
+ * components in the source image are reordered into image planes, but no
+ * colorspace conversion or subsampling is performed. RGB JPEG images can be
+ * decompressed to any of the extended RGB pixel formats or grayscale, but
+ * they cannot be decompressed to YUV images.
+ */
+ TJCS_RGB=0,
+ /**
+ * YCbCr colorspace. YCbCr is not an absolute colorspace but rather a
+ * mathematical transformation of RGB designed solely for storage and
+ * transmission. YCbCr images must be converted to RGB before they can
+ * actually be displayed. In the YCbCr colorspace, the Y (luminance)
+ * component represents the black & white portion of the original image, and
+ * the Cb and Cr (chrominance) components represent the color portion of the
+ * original image. Originally, the analog equivalent of this transformation
+ * allowed the same signal to drive both black & white and color televisions,
+ * but JPEG images use YCbCr primarily because it allows the color data to be
+ * optionally subsampled for the purposes of reducing bandwidth or disk
+ * space. YCbCr is the most common JPEG colorspace, and YCbCr JPEG images
+ * can be compressed from and decompressed to any of the extended RGB pixel
+ * formats or grayscale, or they can be decompressed to YUV planar images.
+ */
+ TJCS_YCbCr,
+ /**
+ * Grayscale colorspace. The JPEG image retains only the luminance data (Y
+ * component), and any color data from the source image is discarded.
+ * Grayscale JPEG images can be compressed from and decompressed to any of
+ * the extended RGB pixel formats or grayscale, or they can be decompressed
+ * to YUV planar images.
+ */
+ TJCS_GRAY,
+ /**
+ * CMYK colorspace. When compressing the JPEG image, the C, M, Y, and K
+ * components in the source image are reordered into image planes, but no
+ * colorspace conversion or subsampling is performed. CMYK JPEG images can
+ * only be decompressed to CMYK pixels.
+ */
+ TJCS_CMYK,
+ /**
+ * YCCK colorspace. YCCK (AKA "YCbCrK") is not an absolute colorspace but
+ * rather a mathematical transformation of CMYK designed solely for storage
+ * and transmission. It is to CMYK as YCbCr is to RGB. CMYK pixels can be
+ * reversibly transformed into YCCK, and as with YCbCr, the chrominance
+ * components in the YCCK pixels can be subsampled without incurring major
+ * perceptual loss. YCCK JPEG images can only be compressed from and
+ * decompressed to CMYK pixels.
+ */
+ TJCS_YCCK
+};
+
+
/**
* Red offset (in bytes) for a given pixel format. This specifies the number
* of bytes that the red component is offset from the start of the pixel. For
* instance, if a pixel of format TJ_BGRX is stored in char pixel[],
* then the red component will be pixel[tjRedOffset[TJ_BGRX]].
*/
-static const int tjRedOffset[TJ_NUMPF] = {0, 2, 0, 2, 3, 1, 0, 0, 2, 3, 1};
+static const int tjRedOffset[TJ_NUMPF] = {0, 2, 0, 2, 3, 1, 0, 0, 2, 3, 1, -1};
/**
* Green offset (in bytes) for a given pixel format. This specifies the number
* of bytes that the green component is offset from the start of the pixel.
@@ -219,19 +301,19 @@ static const int tjRedOffset[TJ_NUMPF] = {0, 2, 0, 2, 3, 1, 0, 0, 2, 3, 1};
* char pixel[], then the green component will be
* pixel[tjGreenOffset[TJ_BGRX]].
*/
-static const int tjGreenOffset[TJ_NUMPF] = {1, 1, 1, 1, 2, 2, 0, 1, 1, 2, 2};
+static const int tjGreenOffset[TJ_NUMPF] = {1, 1, 1, 1, 2, 2, 0, 1, 1, 2, 2, -1};
/**
* Blue offset (in bytes) for a given pixel format. This specifies the number
* of bytes that the Blue component is offset from the start of the pixel. For
* instance, if a pixel of format TJ_BGRX is stored in char pixel[],
* then the blue component will be pixel[tjBlueOffset[TJ_BGRX]].
*/
-static const int tjBlueOffset[TJ_NUMPF] = {2, 0, 2, 0, 1, 3, 0, 2, 0, 1, 3};
+static const int tjBlueOffset[TJ_NUMPF] = {2, 0, 2, 0, 1, 3, 0, 2, 0, 1, 3, -1};
/**
* Pixel size (in bytes) for a given pixel format.
*/
-static const int tjPixelSize[TJ_NUMPF] = {3, 3, 4, 4, 4, 4, 1, 4, 4, 4, 4};
+static const int tjPixelSize[TJ_NUMPF] = {3, 3, 4, 4, 4, 4, 1, 4, 4, 4, 4, 4};
/**
@@ -454,8 +536,8 @@ typedef struct tjtransform
/**
* A callback function that can be used to modify the DCT coefficients
* after they are losslessly transformed but before they are transcoded to a
- * new JPEG file. This allows for custom filters or other transformations to
- * be applied in the frequency domain.
+ * new JPEG image. This allows for custom filters or other transformations
+ * to be applied in the frequency domain.
*
* @param coeffs pointer to an array of transformed DCT coefficients. (NOTE:
* this pointer is not guaranteed to be valid once the callback
@@ -521,11 +603,11 @@ DLLEXPORT tjhandle DLLCALL tjInitCompress(void);
/**
- * Compress an RGB or grayscale image into a JPEG image.
+ * Compress an RGB, grayscale, or CMYK image into a JPEG image.
*
* @param handle a handle to a TurboJPEG compressor or transformer instance
- * @param srcBuf pointer to an image buffer containing RGB or grayscale pixels
- * to be compressed
+ * @param srcBuf pointer to an image buffer containing RGB, grayscale, or
+ * CMYK pixels to be compressed
* @param width width (in pixels) of the source image
* @param pitch bytes per line of the source image. Normally, this should be
* width * #tjPixelSize[pixelFormat] if the image is unpadded,
@@ -686,12 +768,15 @@ DLLEXPORT tjhandle DLLCALL tjInitDecompress(void);
* @param jpegSubsamp pointer to an integer variable that will receive the
* level of chrominance subsampling used when compressing the JPEG image
* (see @ref TJSAMP "Chrominance subsampling options".)
+ * @param jpegColorspace pointer to an integer variable that will receive one
+ * of the JPEG colorspace constants, indicating the colorspace of the
+ * JPEG image (see @ref TJCS "JPEG colorspaces".)
*
* @return 0 if successful, or -1 if an error occurred (see #tjGetErrorStr().)
*/
-DLLEXPORT int DLLCALL tjDecompressHeader2(tjhandle handle,
+DLLEXPORT int DLLCALL tjDecompressHeader3(tjhandle handle,
unsigned char *jpegBuf, unsigned long jpegSize, int *width, int *height,
- int *jpegSubsamp);
+ int *jpegSubsamp, int *jpegColorspace);
/**
@@ -708,7 +793,7 @@ DLLEXPORT tjscalingfactor* DLLCALL tjGetScalingFactors(int *numscalingfactors);
/**
- * Decompress a JPEG image to an RGB or grayscale image.
+ * Decompress a JPEG image to an RGB, grayscale, or CMYK image.
*
* @param handle a handle to a TurboJPEG decompressor or transformer instance
* @param jpegBuf pointer to a buffer containing the JPEG image to decompress
@@ -735,8 +820,8 @@ DLLEXPORT tjscalingfactor* DLLCALL tjGetScalingFactors(int *numscalingfactors);
* calling #TJSCALED() with the JPEG image width and one of the scaling
* factors returned by #tjGetScalingFactors().) You can also be clever
* and use the pitch parameter to skip lines, etc. Setting this
- * parameter to 0 is the equivalent of setting it to scaledWidth
- * * #tjPixelSize[pixelFormat].
+ * parameter to 0 is the equivalent of setting it to
+ * scaledWidth * #tjPixelSize[pixelFormat].
* @param height desired height (in pixels) of the destination image. If this
* is different than the height of the JPEG image being decompressed,
* then TurboJPEG will use scaling in the JPEG decompressor to generate
@@ -949,6 +1034,10 @@ DLLEXPORT int DLLCALL tjEncodeYUV2(tjhandle handle,
DLLEXPORT int DLLCALL tjDecompressHeader(tjhandle handle,
unsigned char *jpegBuf, unsigned long jpegSize, int *width, int *height);
+DLLEXPORT int DLLCALL tjDecompressHeader2(tjhandle handle,
+ unsigned char *jpegBuf, unsigned long jpegSize, int *width, int *height,
+ int *jpegSubsamp);
+
DLLEXPORT int DLLCALL tjDecompress(tjhandle handle,
unsigned char *jpegBuf, unsigned long jpegSize, unsigned char *dstBuf,
int width, int pitch, int height, int pixelSize, int flags);