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