added support for CMYK JPEGs loading (patch 1476078)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@39392 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -89,6 +89,7 @@ All (GUI):
|
|||||||
- Added wxHyperlinkCtrl (Francesco Montorsi)
|
- Added wxHyperlinkCtrl (Francesco Montorsi)
|
||||||
- Added clipboard events (wxEVT_COMMAND_TEXT_COPY/CUT/PASTE)
|
- Added clipboard events (wxEVT_COMMAND_TEXT_COPY/CUT/PASTE)
|
||||||
- Added wxRadioBox::SetItemToolTip()
|
- Added wxRadioBox::SetItemToolTip()
|
||||||
|
- Added support for CMYK JPEG images loading (Robert Wruck)
|
||||||
- Added wxListCtrl::GetSubItemRect() and subitem hit testing (Agron Selimaj)
|
- Added wxListCtrl::GetSubItemRect() and subitem hit testing (Agron Selimaj)
|
||||||
- Added wxKeyEvent::GetModifiers()
|
- Added wxKeyEvent::GetModifiers()
|
||||||
- Added wxDialog::SetEscapeId().
|
- Added wxDialog::SetEscapeId().
|
||||||
|
BIN
samples/image/cmyk.jpg
Normal file
BIN
samples/image/cmyk.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 22 KiB |
@@ -16,7 +16,7 @@
|
|||||||
<files>
|
<files>
|
||||||
horse.png horse.jpg horse.bmp horse.gif horse.pcx horse.pnm horse_ag.pnm horse_rg.pnm
|
horse.png horse.jpg horse.bmp horse.gif horse.pcx horse.pnm horse_ag.pnm horse_rg.pnm
|
||||||
horse.tif horse.xpm horse.cur horse.ico horse3.ani
|
horse.tif horse.xpm horse.cur horse.ico horse3.ani
|
||||||
smile.xbm toucan.png
|
smile.xbm toucan.png cmyk.jpg
|
||||||
</files>
|
</files>
|
||||||
</wx-data>
|
</wx-data>
|
||||||
|
|
||||||
|
@@ -83,6 +83,7 @@ public:
|
|||||||
wxBitmap my_horse_rawgrey_pnm;
|
wxBitmap my_horse_rawgrey_pnm;
|
||||||
|
|
||||||
wxBitmap colorized_horse_jpeg;
|
wxBitmap colorized_horse_jpeg;
|
||||||
|
wxBitmap my_cmyk_jpeg;
|
||||||
|
|
||||||
wxBitmap my_toucan;
|
wxBitmap my_toucan;
|
||||||
wxBitmap my_toucan_flipped_horiz;
|
wxBitmap my_toucan_flipped_horiz;
|
||||||
@@ -484,12 +485,18 @@ MyCanvas::MyCanvas( wxWindow *parent, wxWindowID id,
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
my_horse_jpeg = wxBitmap( image );
|
my_horse_jpeg = wxBitmap( image );
|
||||||
|
|
||||||
// Colorize by rotating green hue to red
|
// Colorize by rotating green hue to red
|
||||||
wxImage::HSVValue greenHSV = wxImage::RGBtoHSV(wxImage::RGBValue(0, 255, 0));
|
wxImage::HSVValue greenHSV = wxImage::RGBtoHSV(wxImage::RGBValue(0, 255, 0));
|
||||||
wxImage::HSVValue redHSV = wxImage::RGBtoHSV(wxImage::RGBValue(255, 0, 0));
|
wxImage::HSVValue redHSV = wxImage::RGBtoHSV(wxImage::RGBValue(255, 0, 0));
|
||||||
image.RotateHue(redHSV.hue - greenHSV.hue);
|
image.RotateHue(redHSV.hue - greenHSV.hue);
|
||||||
colorized_horse_jpeg = wxBitmap( image );
|
colorized_horse_jpeg = wxBitmap( image );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( !image.LoadFile( dir + _T("cmyk.jpg")) )
|
||||||
|
wxLogError(_T("Can't load CMYK JPG image"));
|
||||||
|
else
|
||||||
|
my_cmyk_jpeg = wxBitmap(image);
|
||||||
#endif // wxUSE_LIBJPEG
|
#endif // wxUSE_LIBJPEG
|
||||||
|
|
||||||
#if wxUSE_GIF
|
#if wxUSE_GIF
|
||||||
@@ -685,6 +692,14 @@ void MyCanvas::OnPaint( wxPaintEvent &WXUNUSED(event) )
|
|||||||
if (my_horse_jpeg.Ok())
|
if (my_horse_jpeg.Ok())
|
||||||
dc.DrawBitmap( my_horse_jpeg, 30, 380 );
|
dc.DrawBitmap( my_horse_jpeg, 30, 380 );
|
||||||
|
|
||||||
|
dc.DrawText( _T("Green rotated to red"), 280, 365 );
|
||||||
|
if (colorized_horse_jpeg.Ok())
|
||||||
|
dc.DrawBitmap( colorized_horse_jpeg, 280, 380 );
|
||||||
|
|
||||||
|
dc.DrawText( _T("CMYK JPEG image"), 530, 365 );
|
||||||
|
if (my_cmyk_jpeg.Ok())
|
||||||
|
dc.DrawBitmap( my_cmyk_jpeg, 530, 380 );
|
||||||
|
|
||||||
dc.DrawText( _T("GIF handler"), 30, 595 );
|
dc.DrawText( _T("GIF handler"), 30, 595 );
|
||||||
if (my_horse_gif.Ok())
|
if (my_horse_gif.Ok())
|
||||||
dc.DrawBitmap( my_horse_gif, 30, 610 );
|
dc.DrawBitmap( my_horse_gif, 30, 610 );
|
||||||
@@ -721,8 +736,9 @@ void MyCanvas::OnPaint( wxPaintEvent &WXUNUSED(event) )
|
|||||||
if (my_horse_xpm.Ok())
|
if (my_horse_xpm.Ok())
|
||||||
dc.DrawBitmap( my_horse_xpm, 30, 1760 );
|
dc.DrawBitmap( my_horse_xpm, 30, 1760 );
|
||||||
|
|
||||||
|
// toucans
|
||||||
{
|
{
|
||||||
int x = 200, y = 300, yy = 170;;
|
int x = 750, y = 10, yy = 170;
|
||||||
|
|
||||||
dc.DrawText(wxT("Original toucan"), x+50, y);
|
dc.DrawText(wxT("Original toucan"), x+50, y);
|
||||||
dc.DrawBitmap(my_toucan, x, y+15);
|
dc.DrawBitmap(my_toucan, x, y+15);
|
||||||
@@ -871,15 +887,6 @@ void MyCanvas::OnPaint( wxPaintEvent &WXUNUSED(event) )
|
|||||||
dc.DrawBitmap( my_horse_ani[i], 230 + i * 2 * my_horse_ani[i].GetWidth() , 2420, true );
|
dc.DrawBitmap( my_horse_ani[i], 230 + i * 2 * my_horse_ani[i].GetWidth() , 2420, true );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if wxUSE_LIBJPEG
|
|
||||||
if (colorized_horse_jpeg.Ok())
|
|
||||||
{
|
|
||||||
dc.DrawText( _T("Colorize image by rotating green hue to red"), 30, 2490 );
|
|
||||||
dc.DrawBitmap( colorized_horse_jpeg, 30, 2520 );
|
|
||||||
}
|
|
||||||
#endif // wxUSE_LIBJPEG
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MyCanvas::CreateAntiAliasedBitmap()
|
void MyCanvas::CreateAntiAliasedBitmap()
|
||||||
@@ -959,7 +966,7 @@ END_EVENT_TABLE()
|
|||||||
|
|
||||||
MyFrame::MyFrame()
|
MyFrame::MyFrame()
|
||||||
: wxFrame( (wxFrame *)NULL, wxID_ANY, _T("wxImage sample"),
|
: wxFrame( (wxFrame *)NULL, wxID_ANY, _T("wxImage sample"),
|
||||||
wxPoint(20,20), wxSize(470,360) )
|
wxPoint(20, 20), wxSize(950, 700) )
|
||||||
{
|
{
|
||||||
wxMenuBar *menu_bar = new wxMenuBar();
|
wxMenuBar *menu_bar = new wxMenuBar();
|
||||||
|
|
||||||
|
@@ -202,6 +202,21 @@ void wx_jpeg_io_src( j_decompress_ptr cinfo, wxInputStream& infile )
|
|||||||
src->pub.term_source = wx_term_source;
|
src->pub.term_source = wx_term_source;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void wx_cmyk_to_rgb(unsigned char* rgb, const unsigned char* cmyk)
|
||||||
|
{
|
||||||
|
register int k = 255 - cmyk[3];
|
||||||
|
register int k2 = cmyk[3];
|
||||||
|
register int c;
|
||||||
|
|
||||||
|
c = k + k2 * (255 - cmyk[0]) / 255;
|
||||||
|
rgb[0] = (c > 255) ? 0 : (255 - c);
|
||||||
|
|
||||||
|
c = k + k2 * (255 - cmyk[1]) / 255;
|
||||||
|
rgb[1] = (c > 255) ? 0 : (255 - c);
|
||||||
|
|
||||||
|
c = k + k2 * (255 - cmyk[2]) / 255;
|
||||||
|
rgb[2] = (c > 255) ? 0 : (255 - c);
|
||||||
|
}
|
||||||
|
|
||||||
// temporarily disable the warning C4611 (interaction between '_setjmp' and
|
// temporarily disable the warning C4611 (interaction between '_setjmp' and
|
||||||
// C++ object destruction is non-portable) - I don't see any dtors here
|
// C++ object destruction is non-portable) - I don't see any dtors here
|
||||||
@@ -213,9 +228,7 @@ bool wxJPEGHandler::LoadFile( wxImage *image, wxInputStream& stream, bool verbos
|
|||||||
{
|
{
|
||||||
struct jpeg_decompress_struct cinfo;
|
struct jpeg_decompress_struct cinfo;
|
||||||
struct wx_error_mgr jerr;
|
struct wx_error_mgr jerr;
|
||||||
JSAMPARRAY tempbuf;
|
|
||||||
unsigned char *ptr;
|
unsigned char *ptr;
|
||||||
unsigned stride;
|
|
||||||
|
|
||||||
image->Destroy();
|
image->Destroy();
|
||||||
cinfo.err = jpeg_std_error( &jerr.pub );
|
cinfo.err = jpeg_std_error( &jerr.pub );
|
||||||
@@ -240,7 +253,19 @@ bool wxJPEGHandler::LoadFile( wxImage *image, wxInputStream& stream, bool verbos
|
|||||||
jpeg_create_decompress( &cinfo );
|
jpeg_create_decompress( &cinfo );
|
||||||
wx_jpeg_io_src( &cinfo, stream );
|
wx_jpeg_io_src( &cinfo, stream );
|
||||||
jpeg_read_header( &cinfo, TRUE );
|
jpeg_read_header( &cinfo, TRUE );
|
||||||
|
|
||||||
|
int bytesPerPixel;
|
||||||
|
if ((cinfo.out_color_space == JCS_CMYK) || (cinfo.out_color_space == JCS_YCCK))
|
||||||
|
{
|
||||||
|
cinfo.out_color_space = JCS_CMYK;
|
||||||
|
bytesPerPixel = 4;
|
||||||
|
}
|
||||||
|
else // all the rest is treated as RGB
|
||||||
|
{
|
||||||
cinfo.out_color_space = JCS_RGB;
|
cinfo.out_color_space = JCS_RGB;
|
||||||
|
bytesPerPixel = 3;
|
||||||
|
}
|
||||||
|
|
||||||
jpeg_start_decompress( &cinfo );
|
jpeg_start_decompress( &cinfo );
|
||||||
|
|
||||||
image->Create( cinfo.image_width, cinfo.image_height );
|
image->Create( cinfo.image_width, cinfo.image_height );
|
||||||
@@ -251,15 +276,31 @@ bool wxJPEGHandler::LoadFile( wxImage *image, wxInputStream& stream, bool verbos
|
|||||||
}
|
}
|
||||||
image->SetMask( false );
|
image->SetMask( false );
|
||||||
ptr = image->GetData();
|
ptr = image->GetData();
|
||||||
stride = cinfo.output_width * 3;
|
|
||||||
tempbuf = (*cinfo.mem->alloc_sarray)
|
unsigned stride = cinfo.output_width * bytesPerPixel;
|
||||||
|
JSAMPARRAY tempbuf = (*cinfo.mem->alloc_sarray)
|
||||||
((j_common_ptr) &cinfo, JPOOL_IMAGE, stride, 1 );
|
((j_common_ptr) &cinfo, JPOOL_IMAGE, stride, 1 );
|
||||||
|
|
||||||
while ( cinfo.output_scanline < cinfo.output_height ) {
|
while ( cinfo.output_scanline < cinfo.output_height )
|
||||||
|
{
|
||||||
jpeg_read_scanlines( &cinfo, tempbuf, 1 );
|
jpeg_read_scanlines( &cinfo, tempbuf, 1 );
|
||||||
|
if (cinfo.out_color_space == JCS_RGB)
|
||||||
|
{
|
||||||
memcpy( ptr, tempbuf[0], stride );
|
memcpy( ptr, tempbuf[0], stride );
|
||||||
ptr += stride;
|
ptr += stride;
|
||||||
}
|
}
|
||||||
|
else // CMYK
|
||||||
|
{
|
||||||
|
const unsigned char* inptr = (const unsigned char*) tempbuf[0];
|
||||||
|
for (size_t i = 0; i < cinfo.output_width; i++)
|
||||||
|
{
|
||||||
|
wx_cmyk_to_rgb(ptr, inptr);
|
||||||
|
ptr += 3;
|
||||||
|
inptr += 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
jpeg_finish_decompress( &cinfo );
|
jpeg_finish_decompress( &cinfo );
|
||||||
jpeg_destroy_decompress( &cinfo );
|
jpeg_destroy_decompress( &cinfo );
|
||||||
return true;
|
return true;
|
||||||
|
Reference in New Issue
Block a user