[Digikam-devel] [Bug 149578] libjpeg JPEG subsampling setting is not user-controlable

Gilles Caulier caulier.gilles at gmail.com
Fri Sep 7 15:11:31 BST 2007


------- You are receiving this mail because: -------
You are the assignee for the bug, or are watching the assignee.
         
http://bugs.kde.org/show_bug.cgi?id=149578         




------- Additional Comments From caulier.gilles gmail com  2007-09-07 16:11 -------
SVN commit 709439 by cgilles:

digiKam from KDE3 branch : provide settings to adjust JPEG subsampling factor when new JPEG file is created by editor.
TODO: KDE4PORT
CCBUGS: 149578



 M  +44 -6     libs/dimg/loaders/jpegloader.cpp  
 M  +37 -4     libs/dimg/loaders/jpegsettings.cpp  
 M  +3 -0      libs/dimg/loaders/jpegsettings.h  
 M  +2 -1      libs/widgets/common/filesaveoptionsbox.cpp  
 M  +10 -10    project/project.kdevelop  
 M  +5 -2      utilities/imageeditor/canvas/dimginterface.cpp  
 M  +4 -0      utilities/imageeditor/canvas/iofilesettingscontainer.h  
 M  +2 -0      utilities/imageeditor/editor/editorwindow.cpp  
 M  +2 -0      utilities/setup/setupiofiles.cpp  


--- branches/extragear/kde3/graphics/digikam/libs/dimg/loaders/jpegloader.cpp #709438:709439
 @ -503,19 +503,57  @
 
     QVariant qualityAttr = imageGetAttribute("quality");
     int quality = qualityAttr.isValid() ? qualityAttr.toInt() : 90;
-    
+
     if (quality < 0)
         quality = 90;
     if (quality > 100)
         quality = 100;
-    
+
+    QVariant subSamplingAttr = imageGetAttribute("subsampling");
+    int subsampling = subSamplingAttr.isValid() ? subSamplingAttr.toInt() : 1;  // Medium
+   
     jpeg_set_defaults(&cinfo);
 
-    // B.K.O #130996: set horizontal and vertical Subsampling factor to 1 for a best 
-    // quality of color picture compression. 
-    cinfo.comp_info[0].h_samp_factor = 1;
-    cinfo.comp_info[0].v_samp_factor = 1; 
+    // B.K.O #149578: set horizontal and vertical chroma subsampling factor to encoder.
+    // See this page for details: http://en.wikipedia.org/wiki/Chroma_subsampling
 
+    switch (subsampling)
+    {
+        case 1:  // 2x1, 1x1, 1x1 (4:2:2) : Medium
+        {
+            DDebug() << "Using LibJPEG medium chroma-subsampling (4:2:2)" << endl;
+            cinfo.comp_info[0].h_samp_factor = 2;
+            cinfo.comp_info[0].v_samp_factor = 1;
+            cinfo.comp_info[1].h_samp_factor = 1;
+            cinfo.comp_info[1].v_samp_factor = 1;
+            cinfo.comp_info[2].h_samp_factor = 1;
+            cinfo.comp_info[2].v_samp_factor = 1;
+            break;
+        }
+        case 2:  // 2x2, 1x1, 1x1 (4:1:1) : High
+        {
+            DDebug() << "Using LibJPEG high chroma-subsampling (4:1:1)" << endl;
+            cinfo.comp_info[0].h_samp_factor = 2;
+            cinfo.comp_info[0].v_samp_factor = 2;
+            cinfo.comp_info[1].h_samp_factor = 1;
+            cinfo.comp_info[1].v_samp_factor = 1;
+            cinfo.comp_info[2].h_samp_factor = 1;
+            cinfo.comp_info[2].v_samp_factor = 1;
+            break;
+        }
+        default:  // 1x1 1x1 1x1 (4:4:4) : None
+        {
+            DDebug() << "Using LibJPEG none chroma-subsampling (4:4:4)" << endl;
+            cinfo.comp_info[0].h_samp_factor = 1;
+            cinfo.comp_info[0].v_samp_factor = 1;
+            cinfo.comp_info[1].h_samp_factor = 1;
+            cinfo.comp_info[1].v_samp_factor = 1;
+            cinfo.comp_info[2].h_samp_factor = 1;
+            cinfo.comp_info[2].v_samp_factor = 1;
+            break;
+        }
+    }
+
     jpeg_set_quality(&cinfo, quality, true);
     jpeg_start_compress(&cinfo, true);
 
--- branches/extragear/kde3/graphics/digikam/libs/dimg/loaders/jpegsettings.cpp #709438:709439
 @ -27,6 +27,7  @
 #include <qlabel.h>
 #include <qlayout.h>
 #include <qwhatsthis.h>
+#include <qcombobox.h>
 
 // KDE includes.
 
 @ -54,12 +55,16  @
         labelJPEGcompression = 0;
         JPEGcompression      = 0;
         labelWarning         = 0;
+        subSamplingCB        = 0;
     }
 
     QGridLayout  *JPEGGrid;
 
     QLabel       *labelJPEGcompression;
+    QLabel       *labelSubSampling;
 
+    QComboBox    *subSamplingCB;
+
     KActiveLabel *labelWarning;
 
     KIntNumInput *JPEGcompression;
 @ -94,11 +99,30  @
     d->labelWarning->setLineWidth(1);
     d->labelWarning->setFrameShape(QFrame::Box);
 
+    d->labelSubSampling = new QLabel(i18n("Chroma subsampling:"), this);
+
+    d->subSamplingCB = new QComboBox(false, this);
+    d->subSamplingCB->insertItem(i18n("None"));    // 1x1, 1x1, 1x1 (4:4:4)
+    d->subSamplingCB->insertItem(i18n("Medium"));  // 2x1, 1x1, 1x1 (4:2:2)
+    d->subSamplingCB->insertItem(i18n("High"));    // 2x2, 1x1, 1x1 (4:1:1)
+    QWhatsThis::add(d->subSamplingCB, i18n("<p>The level of chroma subsampling for JPEG images:<p>"
+                                           "<b>None</b>: use 4:4:4 ratio. It does not have any chroma "
+                                           "subsampling at all. This preserves borders and contrasting "
+                                           "colors, but compression is less<p>"
+                                           "<b>Medium</b>: use 4:2:2 ratio. Medium compression; reduces "
+                                           "the bandwidth for the picture by one-third with little to "
+                                           "no visual difference<p>"
+                                           "<b>High</b>: use 4:1:1 ratio. Important compression; suits "
+                                           "images with weak borders but tends to denature colors<p>"
+                                           "<b>Note: JPEG use a lossy compression image algorithm.</b>"));
+
     d->JPEGGrid->addMultiCellWidget(d->labelJPEGcompression, 0, 0, 0, 0);
-    d->JPEGGrid->addMultiCellWidget(d->JPEGcompression, 0, 0, 1, 1);
-    d->JPEGGrid->addMultiCellWidget(d->labelWarning, 0, 0, 2, 2);    
+    d->JPEGGrid->addMultiCellWidget(d->JPEGcompression,      0, 0, 1, 1);
+    d->JPEGGrid->addMultiCellWidget(d->labelSubSampling,     1, 1, 0, 0);    
+    d->JPEGGrid->addMultiCellWidget(d->subSamplingCB,        1, 1, 1, 1);    
+    d->JPEGGrid->addMultiCellWidget(d->labelWarning,         0, 1, 2, 2);    
     d->JPEGGrid->setColStretch(1, 10);
-    d->JPEGGrid->setRowStretch(1, 10);
+    d->JPEGGrid->setRowStretch(2, 10);
 }
 
 JPEGSettings::~JPEGSettings()
 @ -116,5 +140,14  @
     return d->JPEGcompression->value();
 }
 
+void JPEGSettings::setSubSamplingValue(int val)
+{
+    d->subSamplingCB->setCurrentItem(val);
+}
+
+int JPEGSettings::getSubSamplingValue()
+{
+    return d->subSamplingCB->currentItem();
+}
+
 }  // namespace Digikam
-
--- branches/extragear/kde3/graphics/digikam/libs/dimg/loaders/jpegsettings.h #709438:709439
 @ -49,6 +49,9  @
     void setCompressionValue(int val);
     int  getCompressionValue();
 
+    void setSubSamplingValue(int val);
+    int  getSubSamplingValue();
+
 private:
 
     JPEGSettingsPriv* d;
--- branches/extragear/kde3/graphics/digikam/libs/widgets/common/filesaveoptionsbox.cpp #709438:709439
 @ -159,6 +159,7  @
     KConfig* config = kapp->config();
     config->setGroup("ImageViewer Settings");
     config->writeEntry("JPEGCompression", d->JPEGOptions->getCompressionValue());
+    config->writeEntry("JPEGSubSampling", d->JPEGOptions->getSubSamplingValue());
     config->writeEntry("PNGCompression", d->PNGOptions->getCompressionValue());
     config->writeEntry("TIFFCompression", d->TIFFOptions->getCompression());
     config->writeEntry("JPEG2000Compression", d->JPEG2000Options->getCompressionValue());
 @ -171,6 +172,7  @
     KConfig* config = kapp->config();
     config->setGroup("ImageViewer Settings");
     d->JPEGOptions->setCompressionValue( config->readNumEntry("JPEGCompression", 75) );
+    d->JPEGOptions->setCompressionValue( config->readNumEntry("JPEGSubSampling", 1) );  // Medium subsampling
     d->PNGOptions->setCompressionValue( config->readNumEntry("PNGCompression", 9) );
     d->TIFFOptions->setCompression(config->readBoolEntry("TIFFCompression", false));
     d->JPEG2000Options->setCompressionValue( config->readNumEntry("JPEG2000Compression", 75) );
 @ -178,4 +180,3  @
 }
 
 }  // namespace Digikam
-
--- branches/extragear/kde3/graphics/digikam/project/project.kdevelop #709438:709439
 @ -12,10 +12,10  @
     </keywords>
     <projectdirectory>./</projectdirectory>
     <absoluteprojectpath>false</absoluteprojectpath>
-    <description/>
+    <description></description>
     <ignoreparts/>
     <projectname>digikam</projectname>
-    <defaultencoding/>
+    <defaultencoding></defaultencoding>
   </general>
   <kdevfileview>
     <groups>
 @ -75,10 +75,10  @
     <general>
       <dbgshell>libtool</dbgshell>
       <programargs/>
-      <gdbpath/>
-      <configGdbScript/>
-      <runShellScript/>
-      <runGdbScript/>
+      <gdbpath></gdbpath>
+      <configGdbScript></configGdbScript>
+      <runShellScript></runShellScript>
+      <runGdbScript></runGdbScript>
       <breakonloadinglibs>true</breakonloadinglibs>
       <separatetty>false</separatetty>
       <floatingtoolbar>false</floatingtoolbar>
 @ -113,12 +113,12  @
     <run>
       <directoryradio>build</directoryradio>
       <customdirectory>/</customdirectory>
-      <mainprogram>digikam/digikam/digikam</mainprogram>
-      <programargs/>
+      <mainprogram>/home/gilles/Documents/Devel/SVN/branches/graphics/digikam/digikam/digikam</mainprogram>
+      <programargs></programargs>
       <terminal>false</terminal>
       <autocompile>false</autocompile>
       <envvars/>
-      <globaldebugarguments/>
+      <globaldebugarguments></globaldebugarguments>
       <globalcwd>../digikam</globalcwd>
       <useglobalprogram>true</useglobalprogram>
       <autoinstall>false</autoinstall>
 @ -192,7 +192,7  @
       <includePaths>.;</includePaths>
     </codecompletion>
     <creategettersetter>
-      <prefixGet/>
+      <prefixGet></prefixGet>
       <prefixSet>set</prefixSet>
       <prefixVariable>m_,_</prefixVariable>
       <parameterName>theValue</parameterName>
--- branches/extragear/kde3/graphics/digikam/utilities/imageeditor/canvas/dimginterface.cpp #709438:709439
 @ -549,8 +549,11  @
 
     // JPEG file format.
     if ( mimeType.upper() == QString("JPG") || mimeType.upper() == QString("JPEG") || 
-         mimeType.upper() == QString("JPE")) 
-       d->image.setAttribute("quality", iofileSettings->JPEGCompression);
+         mimeType.upper() == QString("JPE"))
+    {
+       d->image.setAttribute("quality",     iofileSettings->JPEGCompression);
+       d->image.setAttribute("subsampling", iofileSettings->JPEGSubSampling);
+    }
 
     // PNG file format.
     if ( mimeType.upper() == QString("PNG") ) 
--- branches/extragear/kde3/graphics/digikam/utilities/imageeditor/canvas/iofilesettingscontainer.h #709438:709439
 @ -43,6 +43,7  @
     IOFileSettingsContainer()
     {
         JPEGCompression     = 75;
+        JPEGSubSampling     = 1;    // Medium subsampling
         PNGCompression      = 9;
         TIFFCompression     = false;
         JPEG2000Compression = 75;
 @ -56,6 +57,9  @
     // JPEG quality value.
     int  JPEGCompression;
 
+    // JPEG chroma subsampling value.
+    int  JPEGSubSampling;
+
     // PNG compression value.
     int  PNGCompression;
 
--- branches/extragear/kde3/graphics/digikam/utilities/imageeditor/editor/editorwindow.cpp #709438:709439
 @ -858,6 +858,8  @
                                                  (float)config->readNumEntry("JPEGCompression", 75)
                                                  + 26.0 - (75.0/100.0));
 
+    m_IOFileSettings->JPEGSubSampling     = config->readNumEntry("JPEGSubSampling", 1);  // Medium subsampling
+
     // PNG compression slider settings : 1 - 9 ==> libpng settings : 100 - 1.
     m_IOFileSettings->PNGCompression      = (int)(((1.0-100.0)/8.0)*
                                                  (float)config->readNumEntry("PNGCompression", 1)
--- branches/extragear/kde3/graphics/digikam/utilities/setup/setupiofiles.cpp #709438:709439
 @ -114,6 +114,7  @
     KConfig* config = kapp->config();
     config->setGroup("ImageViewer Settings");
     config->writeEntry("JPEGCompression", d->JPEGOptions->getCompressionValue());
+    config->writeEntry("JPEGSubSampling", d->JPEGOptions->getSubSamplingValue());
     config->writeEntry("PNGCompression", d->PNGOptions->getCompressionValue());
     config->writeEntry("TIFFCompression", d->TIFFOptions->getCompression());
     config->writeEntry("JPEG2000Compression", d->JPEG2000Options->getCompressionValue());
 @ -126,6 +127,7  @
     KConfig* config = kapp->config();
     config->setGroup("ImageViewer Settings");
     d->JPEGOptions->setCompressionValue(config->readNumEntry("JPEGCompression", 75) );
+    d->JPEGOptions->setCompressionValue( config->readNumEntry("JPEGSubSampling", 1) ); // Medium subsampling
     d->PNGOptions->setCompressionValue(config->readNumEntry("PNGCompression", 9) );
     d->TIFFOptions->setCompression(config->readBoolEntry("TIFFCompression", false));
     d->JPEG2000Options->setCompressionValue( config->readNumEntry("JPEG2000Compression", 75) );



More information about the Digikam-devel mailing list