]> git.saurik.com Git - wxWidgets.git/commitdiff
added support for CMYK JPEGs loading (patch 1476078)
authorVadim Zeitlin <vadim@wxwidgets.org>
Sun, 28 May 2006 20:08:39 +0000 (20:08 +0000)
committerVadim Zeitlin <vadim@wxwidgets.org>
Sun, 28 May 2006 20:08:39 +0000 (20:08 +0000)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@39392 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

docs/changes.txt
samples/image/cmyk.jpg [new file with mode: 0644]
samples/image/image.bkl
samples/image/image.cpp
src/common/imagjpeg.cpp

index f92c2afc8781a242dd3495af114ca6cbb814d181..b97abcd6008c2d255a99d4a7439799d7c823f8c2 100644 (file)
@@ -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 (file)
index 0000000..ff86ed1
Binary files /dev/null and b/samples/image/cmyk.jpg differ
index 31dd7ab998d1b53a583b4e226bbcc6a896a9099c..46dabe387fdf36edc2cc1cc055d3c6eb8ab33aa6 100644 (file)
@@ -16,7 +16,7 @@
         <files>
             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
         </files>
     </wx-data>
 
index b8d131102acce50e1403c5868d648b4aead8768a..edb79dd9da24a4b8411ef8ddd298649c390af5ea 100644 (file)
@@ -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();
 
index 829dc4c796ec09fdc455ce1e5f197b2ea6924554..c10f764da40d3b53794d166fb056d392876d0454 100644 (file)
@@ -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;