filters

kis_openexr_import.cpp
1/*
2 * Copyright (c) 2005 Adrian Page <adrian@pagenet.plus.com>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 * Boston, MA 02110-1301, USA.
18 */
19
20#include <tqstring.h>
21#include <tqfile.h>
22
23#include <kgenericfactory.h>
24#include <KoDocument.h>
25#include <KoFilterChain.h>
26
27#include <half.h>
28#include <ImfRgbaFile.h>
29//#include <ImfStringAttribute.h>
30//#include <ImfMatrixAttribute.h>
31//#include <ImfArray.h>
32//#include <drawImage.h>
33
34#include <iostream>
35
36#include "kis_types.h"
37#include "kis_openexr_import.h"
38#include "kis_doc.h"
39#include "kis_image.h"
40#include "kis_meta_registry.h"
41#include "kis_layer.h"
42#include "kis_paint_layer.h"
43#include "kis_annotation.h"
44#include "kis_colorspace_factory_registry.h"
45#include "kis_iterators_pixel.h"
46#include "kis_abstract_colorspace.h"
47#include "kis_rgb_f32_colorspace.h"
48#include "kis_rgb_f16half_colorspace.h"
49
50using namespace std;
51using namespace Imf;
52using namespace Imath;
53
54typedef KGenericFactory<KisOpenEXRImport, KoFilter> KisOpenEXRImportFactory;
55K_EXPORT_COMPONENT_FACTORY(libchalk_openexr_import, KisOpenEXRImportFactory("kofficefilters"))
56
57KisOpenEXRImport::KisOpenEXRImport(KoFilter *, const char *, const TQStringList&) : KoFilter()
58{
59}
60
61KisOpenEXRImport::~KisOpenEXRImport()
62{
63}
64
65KoFilter::ConversionStatus KisOpenEXRImport::convert(const TQCString& from, const TQCString& to)
66{
67 if (from != "image/x-exr" || to != "application/x-chalk") {
68 return KoFilter::NotImplemented;
69 }
70
71 kdDebug(41008) << "\n\n\nChalk importing from OpenEXR\n";
72
73 KisDoc * doc = dynamic_cast<KisDoc*>(m_chain -> outputDocument());
74 if (!doc) {
75 return KoFilter::CreationError;
76 }
77
78 doc -> prepareForImport();
79
80 TQString filename = m_chain -> inputFile();
81
82 if (filename.isEmpty()) {
83 return KoFilter::FileNotFound;
84 }
85
86 RgbaInputFile file(TQFile::encodeName(filename));
87 Box2i dataWindow = file.dataWindow();
88 Box2i displayWindow = file.displayWindow();
89
90 kdDebug(41008) << "Data window: " << TQRect(dataWindow.min.x, dataWindow.min.y, dataWindow.max.x - dataWindow.min.x + 1, dataWindow.max.y - dataWindow.min.y + 1) << endl;
91 kdDebug(41008) << "Display window: " << TQRect(displayWindow.min.x, displayWindow.min.y, displayWindow.max.x - displayWindow.min.x + 1, displayWindow.max.y - displayWindow.min.y + 1) << endl;
92
93 int imageWidth = displayWindow.max.x - displayWindow.min.x + 1;
94 int imageHeight = displayWindow.max.y - displayWindow.min.y + 1;
95
96 TQString imageName = "Imported from OpenEXR";
97
98 int dataWidth = dataWindow.max.x - dataWindow.min.x + 1;
99 int dataHeight = dataWindow.max.y - dataWindow.min.y + 1;
100
101 KisRgbF16HalfColorSpace *cs = static_cast<KisRgbF16HalfColorSpace *>((KisMetaRegistry::instance()->csRegistry()->getColorSpace(KisID("RGBAF16HALF", ""),"")));
102
103 if (cs == 0) {
104 return KoFilter::InternalError;
105 }
106
107 doc -> undoAdapter() -> setUndo(false);
108
109 KisImageSP image = new KisImage(doc->undoAdapter(), imageWidth, imageHeight, cs, imageName);
110
111 if (image == 0) {
112 return KoFilter::CreationError;
113 }
114
115 KisPaintLayerSP layer = dynamic_cast<KisPaintLayer*>(image->newLayer(image -> nextLayerName(), OPACITY_OPAQUE).data());
116
117 if (layer == 0) {
118 return KoFilter::CreationError;
119 }
120
121 TQMemArray<Rgba> pixels(dataWidth);
122
123 for (int y = 0; y < dataHeight; ++y) {
124
125 file.setFrameBuffer(pixels.data() - dataWindow.min.x - (dataWindow.min.y + y) * dataWidth, 1, dataWidth);
126 file.readPixels(dataWindow.min.y + y);
127
128 KisHLineIterator it = layer->paintDevice()->createHLineIterator(dataWindow.min.x, dataWindow.min.y + y, dataWidth, true);
129 Rgba *rgba = pixels.data();
130
131 while (!it.isDone()) {
132
133 // XXX: For now unmultiply the alpha, though compositing will be faster if we
134 // keep it premultiplied.
135 half unmultipliedRed = rgba -> r;
136 half unmultipliedGreen = rgba -> g;
137 half unmultipliedBlue = rgba -> b;
138
139 if (rgba -> a >= HALF_EPSILON) {
140 unmultipliedRed /= rgba -> a;
141 unmultipliedGreen /= rgba -> a;
142 unmultipliedBlue /= rgba -> a;
143 }
144
145 cs -> setPixel(it.rawData(), unmultipliedRed, unmultipliedGreen, unmultipliedBlue, rgba -> a);
146 ++it;
147 ++rgba;
148 }
149 }
150
151 layer->setDirty();
152 doc -> setCurrentImage(image);
153 doc -> undoAdapter() -> setUndo(true);
154 doc -> setModified(false);
155
156 return KoFilter::OK;
157}
158
159#include "kis_openexr_import.moc"
160