filters

kis_tiff_ycbcr_reader.cpp
1/*
2 * Copyright (c) 2006 Cyrille Berger <cberger@cberger.net>
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 "kis_tiff_ycbcr_reader.h"
21
22#include <kis_iterators_pixel.h>
23#include <kis_paint_device.h>
24
25#include "kis_tiff_stream.h"
26
27
28KisTIFFYCbCrReaderTarget8Bit::KisTIFFYCbCrReaderTarget8Bit( KisPaintDeviceSP device, TQ_UINT8* poses, int8 alphapos, uint8 sourceDepth, uint8 nbcolorssamples, uint8 extrasamplescount, cmsHTRANSFORM transformProfile, KisTIFFPostProcessor* postprocessor, uint16 hsub, uint16 vsub, KisTIFFYCbCr::Position position ) : KisTIFFReaderBase(device, poses, alphapos, sourceDepth, nbcolorssamples, extrasamplescount, transformProfile, postprocessor), m_hsub(hsub), m_vsub(vsub), m_position(position)
29{
30 // Initialize the buffer
31 TQ_INT32 imagewidth = device->image()->width();
32 if(2*(imagewidth / 2) != imagewidth) imagewidth++;
33 m_bufferWidth = imagewidth / m_hsub;
34 TQ_INT32 imageheight = device->image()->height();
35 if(2*(imageheight / 2) != imageheight) imageheight++;
36 m_bufferHeight = imageheight / m_vsub;
37 m_bufferCb = new TQ_UINT8[ m_bufferWidth * m_bufferHeight ];
38 m_bufferCr = new TQ_UINT8[ m_bufferWidth * m_bufferHeight ];
39}
40
41KisTIFFYCbCrReaderTarget8Bit::~KisTIFFYCbCrReaderTarget8Bit()
42{
43 delete[] m_bufferCb;
44 delete[] m_bufferCr;
45}
46
47uint KisTIFFYCbCrReaderTarget8Bit::copyDataToChannels( TQ_UINT32 x, TQ_UINT32 y, TQ_UINT32 dataWidth, TIFFStreamBase* tiffstream)
48{
49 int numcols = dataWidth / m_hsub;
50 double coeff = TQ_UINT8_MAX / (double)( pow(2, sourceDepth() ) - 1 );
51// kdDebug(41008) << " depth expension coefficient : " << coeff << endl;
52// kdDebug(41008) << " y = " << y << endl;
53 uint buffPos = y / m_vsub * m_bufferWidth + x / m_hsub ;
54 for(int index = 0; index < numcols; index++)
55 {
56 KisHLineIterator it = paintDevice() -> createHLineIterator(x + m_hsub * index, y, m_hsub, true);
57 for( int vindex = 0; vindex < m_vsub; vindex++)
58 {
59 while( !it.isDone() )
60 {
61 TQ_UINT8 *d = it.rawData();
62 d[0] = (TQ_UINT8)( tiffstream->nextValue() * coeff );
63 d[3] = TQ_UINT8_MAX;
64 for(int k = 0; k < nbExtraSamples(); k++)
65 {
66 if(k == alphaPos())
67 d[3] = (TQ_UINT32) ( tiffstream->nextValue() * coeff );
68 else
69 tiffstream->nextValue();
70 }
71 ++it;
72 }
73 it.nextRow();
74 }
75 m_bufferCb[ buffPos ] = (TQ_UINT8)(tiffstream->nextValue() * coeff);
76 m_bufferCr[ buffPos ] = (TQ_UINT8)(tiffstream->nextValue() * coeff);
77 buffPos ++;
78 }
79 return m_vsub;
80}
81
82void KisTIFFYCbCrReaderTarget8Bit::finalize()
83{
84 KisHLineIterator it = paintDevice() -> createHLineIterator(0, 0, paintDevice()->image()->width(), true);
85 for(int y = 0; y < paintDevice()->image()->height(); y++)
86 {
87 int x = 0;
88 while(!it.isDone())
89 {
90 TQ_UINT8 *d = it.rawData();
91 int index = x/m_hsub + y/m_vsub * m_bufferWidth;
92 d[1] = m_bufferCb[ index ];
93 d[2] = m_bufferCr[ index ];
94 ++it; ++x;
95 }
96 it.nextRow();
97 }
98}
99
100KisTIFFYCbCrReaderTarget16Bit::KisTIFFYCbCrReaderTarget16Bit( KisPaintDeviceSP device, TQ_UINT8* poses, int8 alphapos, uint8 sourceDepth, uint8 nbcolorssamples, uint8 extrasamplescount, cmsHTRANSFORM transformProfile, KisTIFFPostProcessor* postprocessor, uint16 hsub, uint16 vsub, KisTIFFYCbCr::Position position ) : KisTIFFReaderBase(device, poses, alphapos, sourceDepth, nbcolorssamples, extrasamplescount, transformProfile, postprocessor), m_hsub(hsub), m_vsub(vsub), m_position(position)
101{
102 // Initialize the buffer
103 TQ_INT32 imagewidth = device->image()->width();
104 if(2*(imagewidth / 2) != imagewidth) imagewidth++;
105 m_bufferWidth = imagewidth / m_hsub;
106 TQ_INT32 imageheight = device->image()->height();
107 if(2*(imageheight / 2) != imageheight) imageheight++;
108 m_bufferHeight = imageheight / m_vsub;
109 m_bufferCb = new TQ_UINT16[ m_bufferWidth * m_bufferHeight ];
110 m_bufferCr = new TQ_UINT16[ m_bufferWidth * m_bufferHeight ];
111}
112
113KisTIFFYCbCrReaderTarget16Bit::~KisTIFFYCbCrReaderTarget16Bit()
114{
115 delete[] m_bufferCb;
116 delete[] m_bufferCr;
117}
118
119uint KisTIFFYCbCrReaderTarget16Bit::copyDataToChannels( TQ_UINT32 x, TQ_UINT32 y, TQ_UINT32 dataWidth, TIFFStreamBase* tiffstream)
120{
121 int numcols = dataWidth / m_hsub;
122 double coeff = TQ_UINT16_MAX / (double)( pow(2, sourceDepth() ) - 1 );
123// kdDebug(41008) << " depth expension coefficient : " << coeff << endl;
124// kdDebug(41008) << " y = " << y << endl;
125 uint buffPos = y / m_vsub * m_bufferWidth + x / m_hsub ;
126 for(int index = 0; index < numcols; index++)
127 {
128 KisHLineIterator it = paintDevice() -> createHLineIterator(x + m_hsub * index, y, m_hsub, true);
129 for( int vindex = 0; vindex < m_vsub; vindex++)
130 {
131 while( !it.isDone() )
132 {
133 TQ_UINT16 *d = reinterpret_cast<TQ_UINT16 *>(it.rawData());
134 d[0] = (TQ_UINT16)( tiffstream->nextValue() * coeff );
135 d[3] = TQ_UINT16_MAX;
136 for(int k = 0; k < nbExtraSamples(); k++)
137 {
138 if(k == alphaPos())
139 d[3] = (TQ_UINT32) ( tiffstream->nextValue() * coeff );
140 else
141 tiffstream->nextValue();
142 }
143 ++it;
144 }
145 it.nextRow();
146 }
147 m_bufferCb[ buffPos ] = (TQ_UINT16)(tiffstream->nextValue() * coeff);
148 m_bufferCr[ buffPos ] = (TQ_UINT16)(tiffstream->nextValue() * coeff);
149 buffPos ++;
150 }
151 return m_vsub;
152}
153
154void KisTIFFYCbCrReaderTarget16Bit::finalize()
155{
156 KisHLineIterator it = paintDevice() -> createHLineIterator(0, 0, paintDevice()->image()->width(), true);
157 for(int y = 0; y < paintDevice()->image()->height(); y++)
158 {
159 int x = 0;
160 while(!it.isDone())
161 {
162 TQ_UINT16 *d = reinterpret_cast<TQ_UINT16 *>(it.rawData());
163 int index = x/m_hsub + y/m_vsub * m_bufferWidth;
164 d[1] = m_bufferCb[ index ];
165 d[2] = m_bufferCr[ index ];
166 ++it; ++x;
167 }
168 it.nextRow();
169 }
170}