From: Vadim Zeitlin Date: Sun, 28 May 2006 20:08:39 +0000 (+0000) Subject: added support for CMYK JPEGs loading (patch 1476078) X-Git-Url: https://git.saurik.com/wxWidgets.git/commitdiff_plain/234fedd2d3f7bb618e1b640ca29ad73545c2129b 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 --- diff --git a/docs/changes.txt b/docs/changes.txt index f92c2afc87..b97abcd600 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -89,6 +89,7 @@ All (GUI): - Added wxHyperlinkCtrl (Francesco Montorsi) - Added clipboard events (wxEVT_COMMAND_TEXT_COPY/CUT/PASTE) - Added wxRadioBox::SetItemToolTip() +- Added support for CMYK JPEG images loading (Robert Wruck) - Added wxListCtrl::GetSubItemRect() and subitem hit testing (Agron Selimaj) - Added wxKeyEvent::GetModifiers() - Added wxDialog::SetEscapeId(). diff --git a/samples/image/cmyk.jpg b/samples/image/cmyk.jpg new file mode 100644 index 0000000000..ff86ed1c81 Binary files /dev/null and b/samples/image/cmyk.jpg differ diff --git a/samples/image/image.bkl b/samples/image/image.bkl index 31dd7ab998..46dabe387f 100644 --- a/samples/image/image.bkl +++ b/samples/image/image.bkl @@ -16,7 +16,7 @@ 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 - smile.xbm toucan.png + smile.xbm toucan.png cmyk.jpg diff --git a/samples/image/image.cpp b/samples/image/image.cpp index b8d131102a..edb79dd9da 100644 --- a/samples/image/image.cpp +++ b/samples/image/image.cpp @@ -83,6 +83,7 @@ public: wxBitmap my_horse_rawgrey_pnm; wxBitmap colorized_horse_jpeg; + wxBitmap my_cmyk_jpeg; wxBitmap my_toucan; wxBitmap my_toucan_flipped_horiz; @@ -484,12 +485,18 @@ MyCanvas::MyCanvas( wxWindow *parent, wxWindowID id, else { my_horse_jpeg = wxBitmap( image ); + // Colorize by rotating green hue to red wxImage::HSVValue greenHSV = wxImage::RGBtoHSV(wxImage::RGBValue(0, 255, 0)); wxImage::HSVValue redHSV = wxImage::RGBtoHSV(wxImage::RGBValue(255, 0, 0)); image.RotateHue(redHSV.hue - greenHSV.hue); 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 #if wxUSE_GIF @@ -685,6 +692,14 @@ void MyCanvas::OnPaint( wxPaintEvent &WXUNUSED(event) ) if (my_horse_jpeg.Ok()) 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 ); if (my_horse_gif.Ok()) dc.DrawBitmap( my_horse_gif, 30, 610 ); @@ -721,8 +736,9 @@ void MyCanvas::OnPaint( wxPaintEvent &WXUNUSED(event) ) if (my_horse_xpm.Ok()) 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.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 ); } } - -#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() @@ -959,7 +966,7 @@ END_EVENT_TABLE() MyFrame::MyFrame() : 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(); diff --git a/src/common/imagjpeg.cpp b/src/common/imagjpeg.cpp index 829dc4c796..c10f764da4 100644 --- a/src/common/imagjpeg.cpp +++ b/src/common/imagjpeg.cpp @@ -202,6 +202,21 @@ void wx_jpeg_io_src( j_decompress_ptr cinfo, wxInputStream& infile ) 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 // 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 wx_error_mgr jerr; - JSAMPARRAY tempbuf; unsigned char *ptr; - unsigned stride; image->Destroy(); cinfo.err = jpeg_std_error( &jerr.pub ); @@ -240,7 +253,19 @@ bool wxJPEGHandler::LoadFile( wxImage *image, wxInputStream& stream, bool verbos jpeg_create_decompress( &cinfo ); wx_jpeg_io_src( &cinfo, stream ); jpeg_read_header( &cinfo, TRUE ); - cinfo.out_color_space = JCS_RGB; + + 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; + bytesPerPixel = 3; + } + jpeg_start_decompress( &cinfo ); image->Create( cinfo.image_width, cinfo.image_height ); @@ -251,15 +276,31 @@ bool wxJPEGHandler::LoadFile( wxImage *image, wxInputStream& stream, bool verbos } image->SetMask( false ); ptr = image->GetData(); - stride = cinfo.output_width * 3; - tempbuf = (*cinfo.mem->alloc_sarray) - ((j_common_ptr) &cinfo, JPOOL_IMAGE, stride, 1 ); - while ( cinfo.output_scanline < cinfo.output_height ) { + unsigned stride = cinfo.output_width * bytesPerPixel; + JSAMPARRAY tempbuf = (*cinfo.mem->alloc_sarray) + ((j_common_ptr) &cinfo, JPOOL_IMAGE, stride, 1 ); + + while ( cinfo.output_scanline < cinfo.output_height ) + { jpeg_read_scanlines( &cinfo, tempbuf, 1 ); - memcpy( ptr, tempbuf[0], stride ); - ptr += stride; + if (cinfo.out_color_space == JCS_RGB) + { + memcpy( ptr, tempbuf[0], 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_destroy_decompress( &cinfo ); return true;