00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "kis_tiff_writer_visitor.h"
00021
00022 #include <kmessagebox.h>
00023 #include <klocale.h>
00024
00025 #include <kis_annotation.h>
00026 #include <kis_colorspace.h>
00027 #include <kis_group_layer.h>
00028 #include <kis_image.h>
00029 #include <kis_paint_layer.h>
00030 #include <kis_types.h>
00031
00032 #include "kis_tiff_converter.h"
00033
00034 namespace {
00035 bool writeColorSpaceInformation( TIFF* image, KisColorSpace * cs, uint16& color_type, uint16& sample_format )
00036 {
00037 sample_format = SAMPLEFORMAT_UINT;
00038 if ( cs->id() == KisID("GRAYA") || cs->id() == KisID("GRAYA16") )
00039 {
00040 color_type = PHOTOMETRIC_MINISBLACK;
00041 return true;
00042 }
00043 if ( cs->id() == KisID("RGBA") || cs->id() == KisID("RGBA16") )
00044 {
00045 color_type = PHOTOMETRIC_RGB;
00046 return true;
00047 }
00048 if ( cs->id() == KisID("RGBAF16HALF") || cs->id() == KisID("RGBAF32") )
00049 {
00050 color_type = PHOTOMETRIC_RGB;
00051 sample_format = SAMPLEFORMAT_IEEEFP;
00052 return true;
00053 }
00054 if ( cs->id() == KisID("CMYK") || cs->id() == KisID("CMYKA16") )
00055 {
00056 color_type = PHOTOMETRIC_SEPARATED;
00057 TIFFSetField(image, TIFFTAG_INKSET, INKSET_CMYK);
00058 return true;
00059 }
00060 if ( cs->id() == KisID("LABA") )
00061 {
00062 color_type = PHOTOMETRIC_CIELAB;
00063 return true;
00064 }
00065
00066 KMessageBox::error(0, i18n("Cannot export images in %1.\n").arg(cs->id().name()) ) ;
00067 return false;
00068
00069 }
00070 }
00071
00072 KisTIFFWriterVisitor::KisTIFFWriterVisitor(TIFF*img, KisTIFFOptions* options) : m_image(img), m_options(options)
00073 {
00074 }
00075
00076 KisTIFFWriterVisitor::~KisTIFFWriterVisitor()
00077 {
00078 }
00079
00080 bool KisTIFFWriterVisitor::saveAlpha() { return m_options->alpha; }
00081
00082 bool KisTIFFWriterVisitor::copyDataToStrips( KisHLineIterator it, tdata_t buff, uint8 depth, uint8 nbcolorssamples, Q_UINT8* poses)
00083 {
00084 if(depth == 32)
00085 {
00086 Q_UINT32 *dst = reinterpret_cast<Q_UINT32 *>(buff);
00087 while (!it.isDone()) {
00088 const Q_UINT32 *d = reinterpret_cast<const Q_UINT32 *>(it.rawData());
00089 int i;
00090 for(i = 0; i < nbcolorssamples; i++)
00091 {
00092 *(dst++) = d[poses[i]];
00093 }
00094 if(saveAlpha()) *(dst++) = d[poses[i]];
00095 ++it;
00096 }
00097 return true;
00098 } else if(depth == 16)
00099 {
00100 Q_UINT16 *dst = reinterpret_cast<Q_UINT16 *>(buff);
00101 while (!it.isDone()) {
00102 const Q_UINT16 *d = reinterpret_cast<const Q_UINT16 *>(it.rawData());
00103 int i;
00104 for(i = 0; i < nbcolorssamples; i++)
00105 {
00106 *(dst++) = d[poses[i]];
00107 }
00108 if(saveAlpha()) *(dst++) = d[poses[i]];
00109 ++it;
00110 }
00111 return true;
00112 } else if(depth == 8) {
00113 Q_UINT8 *dst = reinterpret_cast<Q_UINT8 *>(buff);
00114 while (!it.isDone()) {
00115 const Q_UINT8 *d = it.rawData();
00116 int i;
00117 for(i = 0; i < nbcolorssamples; i++)
00118 {
00119 *(dst++) = d[poses[i]];
00120 }
00121 if(saveAlpha()) *(dst++) = d[poses[i]];
00122 ++it;
00123 }
00124 return true;
00125 }
00126 return false;
00127 }
00128
00129
00130 bool KisTIFFWriterVisitor::visit(KisPaintLayer *layer)
00131 {
00132 kdDebug(41008) << "visiting on paint layer " << layer->name() << "\n";
00133 KisPaintDeviceSP pd = layer->paintDevice();
00134
00135 int depth = 8 * pd->pixelSize() / pd->nChannels();
00136 TIFFSetField(image(), TIFFTAG_BITSPERSAMPLE, depth);
00137
00138 if(saveAlpha())
00139 {
00140 TIFFSetField(image(), TIFFTAG_SAMPLESPERPIXEL, pd->nChannels());
00141 uint16 sampleinfo[1] = { EXTRASAMPLE_UNASSALPHA };
00142 TIFFSetField(image(), TIFFTAG_EXTRASAMPLES, 1, sampleinfo);
00143 } else {
00144 TIFFSetField(image(), TIFFTAG_SAMPLESPERPIXEL, pd->nChannels() - 1);
00145 TIFFSetField(image(), TIFFTAG_EXTRASAMPLES, 0);
00146 }
00147
00148 uint16 color_type;
00149 uint16 sample_format;
00150 if(!writeColorSpaceInformation(image(), pd->colorSpace(), color_type, sample_format))
00151 {
00152 return false;
00153 }
00154 TIFFSetField(image(), TIFFTAG_PHOTOMETRIC, color_type);
00155 TIFFSetField(image(), TIFFTAG_SAMPLEFORMAT, sample_format);
00156 TIFFSetField(image(), TIFFTAG_IMAGEWIDTH, layer->image()->width());
00157 TIFFSetField(image(), TIFFTAG_IMAGELENGTH, layer->image()->height());
00158
00159
00160 TIFFSetField(image(), TIFFTAG_COMPRESSION, m_options->compressionType);
00161 TIFFSetField(image(), TIFFTAG_FAXMODE, m_options->faxMode);
00162 TIFFSetField(image(), TIFFTAG_JPEGQUALITY, m_options->jpegQuality);
00163 TIFFSetField(image(), TIFFTAG_ZIPQUALITY, m_options->deflateCompress);
00164 TIFFSetField(image(), TIFFTAG_PIXARLOGQUALITY, m_options->pixarLogCompress);
00165
00166
00167 TIFFSetField(image(), TIFFTAG_PREDICTOR, m_options->predictor);
00168
00169
00170 TIFFSetField(image(), TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
00171
00172 TIFFSetField(image(), TIFFTAG_ROWSPERSTRIP, 8);
00173
00174
00175 KisProfile* profile = pd->colorSpace()->getProfile();
00176 if(profile)
00177 {
00178 QByteArray ba = profile->annotation()->annotation();
00179 TIFFSetField(image(), TIFFTAG_ICCPROFILE, ba.size(),ba.data());
00180 }
00181 tsize_t stripsize = TIFFStripSize(image());
00182 tdata_t buff = _TIFFmalloc(stripsize);
00183 Q_INT32 height = layer->image()->height();
00184 Q_INT32 width = layer->image()->width();
00185 bool r = true;
00186 for (int y = 0; y < height; y++) {
00187 KisHLineIterator it = layer->paintDevice()->createHLineIterator(0, y, width, false);
00188 switch(color_type)
00189 {
00190 case PHOTOMETRIC_MINISBLACK:
00191 {
00192 Q_UINT8 poses[]={ 0,1 };
00193 r = copyDataToStrips(it, buff, depth, 1, poses);
00194 }
00195 break;
00196 case PHOTOMETRIC_RGB:
00197 {
00198 Q_UINT8 poses[]={ 2, 1, 0, 3};
00199 r = copyDataToStrips(it, buff, depth, 3, poses);
00200 }
00201 break;
00202 case PHOTOMETRIC_SEPARATED:
00203 {
00204 Q_UINT8 poses[]={ 0, 1, 2, 3, 4 };
00205 r = copyDataToStrips(it, buff, depth, 4, poses);
00206 }
00207 break;
00208 case PHOTOMETRIC_CIELAB:
00209 {
00210 Q_UINT8 poses[]={ 0, 1, 2, 3 };
00211 r = copyDataToStrips(it, buff, depth, 3, poses);
00212 }
00213 break;
00214 return false;
00215 }
00216 if(!r) return false;
00217 TIFFWriteScanline(image(), buff, y, (tsample_t) -1);
00218 }
00219 _TIFFfree(buff);
00220 TIFFWriteDirectory(image());
00221 return true;
00222 }
00223 bool KisTIFFWriterVisitor::visit(KisGroupLayer *layer)
00224 {
00225 kdDebug(41008) << "Visiting on grouplayer " << layer->name() << "\n";
00226 KisLayerSP child = layer->firstChild();
00227 while (child) {
00228 child->accept(*this);
00229 child = child->nextSibling();
00230 }
00231 return true;
00232 }
00233
00234 bool KisTIFFWriterVisitor::visit(KisPartLayer *)
00235 {
00236 return true;
00237 }