Add CMYK support to the TurboJPEG C API

This commit is contained in:
DRC
2013-08-23 02:49:25 +00:00
parent 9ad7a4c6ca
commit 24668df1df
13 changed files with 392 additions and 91 deletions

View File

@@ -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;