aboutsummaryrefslogtreecommitdiff
path: root/turbojpeg.c
diff options
context:
space:
mode:
authordcommander <dcommander@632fc199-4ca6-4c93-a231-07263d6284db>2013-08-23 02:49:25 +0000
committerdcommander <dcommander@632fc199-4ca6-4c93-a231-07263d6284db>2013-08-23 02:49:25 +0000
commit1ebbcfafe09ce2f1b6e12ae2f73539da2813f07e (patch)
treea46869cdd4ac1f2b409874be7b240b582b33bc9b /turbojpeg.c
parent72ce08133b075b95e8cdd184505339b47c653989 (diff)
Add CMYK support to the TurboJPEG C API
git-svn-id: svn://svn.code.sf.net/p/libjpeg-turbo/code/trunk@1019 632fc199-4ca6-4c93-a231-07263d6284db
Diffstat (limited to 'turbojpeg.c')
-rw-r--r--turbojpeg.c67
1 files changed, 55 insertions, 12 deletions
diff --git a/turbojpeg.c b/turbojpeg.c
index 94918c9..b0acc55 100644
--- a/turbojpeg.c
+++ b/turbojpeg.c
@@ -187,6 +187,8 @@ static int setCompDefaults(struct jpeg_compress_struct *cinfo,
cinfo->in_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; i<NUMSUBOPT; i++)
{
- if(dinfo->num_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; k<dinfo->num_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;