1 /*****************************************************************************\
2 Scaler.cpp : Implimentation for the Scaler class
3
4 Copyright (c) 1996 - 2015, HP Co.
5 All rights reserved.
6
7 Redistribution and use in source and binary forms, with or without
8 modification, are permitted provided that the following conditions
9 are met:
10 1. Redistributions of source code must retain the above copyright
11 notice, this list of conditions and the following disclaimer.
12 2. Redistributions in binary form must reproduce the above copyright
13 notice, this list of conditions and the following disclaimer in the
14 documentation and/or other materials provided with the distribution.
15 3. Neither the name of HP nor the names of its
16 contributors may be used to endorse or promote products derived
17 from this software without specific prior written permission.
18
19 THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR IMPLIED
20 WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
21 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
22 NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
24 TO, PATENT INFRINGEMENT; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
25 OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
26 ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28 THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 \*****************************************************************************/
30
31 #include "CommonDefinitions.h"
32 #include "Processor.h"
33 #include "Scaler.h"
34
35 #define MAX_OUTPUT_RASTERS 32
36
Scaler(unsigned int inputwidth,unsigned int numerator,unsigned int denominator,bool bVIP,unsigned int BytesPerPixel,unsigned int iNumInks)37 Scaler::Scaler(unsigned int inputwidth, unsigned int numerator,
38 unsigned int denominator, bool bVIP, unsigned int BytesPerPixel,
39 unsigned int iNumInks)
40 {
41
42 iInputWidth = inputwidth;
43 rowremainder = remainder;
44 NumInks = iNumInks;
45 vip = bVIP;
46
47 ScaleFactor= (float)numerator / (float)denominator;
48 if (ScaleFactor > (float)MAX_OUTPUT_RASTERS) //
49 {
50 constructor_error = INDEX_OUT_OF_RANGE;
51 return;
52 }
53 int factor = (int)ScaleFactor;
54 float rem = ScaleFactor - (float)factor;
55 rem *= 1000;
56 remainder = (int)rem;
57
58 iOutputWidth = (int) (((float)iInputWidth / (float)denominator) *
59 (float)numerator);
60 iOutputWidth++; // safety measure to protect against roundoff error
61
62 if (numerator == denominator)
63 scaling = false;
64 else scaling = true;
65
66 // ScaleBound=max number of output rows per input row;
67 // i.e., if scale=4.28, then sometimes 5 rows will come out
68
69 int ScaleBound = int(ScaleFactor);
70 if (ScaleFactor > (float) ScaleBound)
71 ScaleBound++;
72
73 // allocate a buffer for one output row
74 int RSBuffSize = (int) (((float)(BytesPerPixel*iOutputWidth)) * ScaleBound );
75 pOutputBuffer[COLORTYPE_COLOR] = (BYTE *) new BYTE[RSBuffSize];
76 if (pOutputBuffer[COLORTYPE_COLOR] == NULL)
77 {
78 constructor_error = ALLOCMEM_ERROR;
79 return;
80 }
81 int BlackBuffSize = (int) (((float) (iOutputWidth)) * ScaleBound );
82 pOutputBuffer[COLORTYPE_BLACK] = (BYTE*) new BYTE[BlackBuffSize];
83 if (pOutputBuffer[COLORTYPE_BLACK] == NULL)
84 {
85 constructor_error = ALLOCMEM_ERROR;
86 return;
87 }
88
89 if (ScaleFactor < 2.0)
90 ReplicateOnly = true;
91 else
92 ReplicateOnly = false;
93
94 if (ScaleFactor > (float) factor)
95 fractional = true;
96 else fractional = false;
97 }
98
~Scaler()99 Scaler::~Scaler ()
100 {
101 for (int i = COLORTYPE_COLOR; i < MAX_COLORTYPE; i++)
102 {
103 if (pOutputBuffer[i])
104 {
105 delete [] pOutputBuffer[i];
106 pOutputBuffer[i] = NULL;
107 }
108 }
109 }
110
GetMaxOutputWidth()111 unsigned int Scaler::GetMaxOutputWidth()
112 {
113 if (myplane == COLORTYPE_COLOR)
114 {
115 return (iOutputWidth-1)*NUMBER_PLANES; // we padded it in case of roundoff error
116 }
117 else
118 {
119 return (iOutputWidth-1); // we padded it in case of roundoff error
120 }
121 }
122
Process(RASTERDATA * raster_in)123 bool Scaler::Process(RASTERDATA* raster_in)
124 {
125 iRastersDelivered=0;
126
127 if (raster_in == NULL || (raster_in->rasterdata[COLORTYPE_COLOR] == NULL && raster_in->rasterdata[COLORTYPE_BLACK] == NULL))
128 {
129 rowremainder=remainder;
130 return false;
131 }
132
133 if (!scaling)
134 {
135 // just copy both to output buffer
136 for (int i = COLORTYPE_COLOR; i < MAX_COLORTYPE; i++)
137 {
138 if (raster_in->rasterdata[i])
139 {
140 memcpy(pOutputBuffer[i], raster_in->rasterdata[i], raster_in->rastersize[i]);
141 }
142 }
143 iRastersReady = 1;
144 return true;
145 }
146
147 if (myplane == COLORTYPE_COLOR)
148 {
149 if (raster_in->rasterdata[COLORTYPE_BLACK])
150 {
151 memcpy(pOutputBuffer[COLORTYPE_BLACK], raster_in->rasterdata[COLORTYPE_BLACK], raster_in->rastersize[COLORTYPE_BLACK]);
152 }
153 }
154
155 if (myplane == COLORTYPE_BLACK)
156 {
157 if (raster_in->rasterdata[COLORTYPE_COLOR])
158 {
159 memcpy(pOutputBuffer[COLORTYPE_COLOR], raster_in->rasterdata[COLORTYPE_COLOR], raster_in->rastersize[COLORTYPE_COLOR]);
160 }
161 }
162
163 // multiply row
164 unsigned int ifactor = (unsigned int) (int) ScaleFactor;
165 unsigned int targptr=0;
166 unsigned int sourceptr=0;
167 unsigned int rem = remainder;
168
169 if (myplane == COLORTYPE_COLOR || myplane == COLORTYPE_BOTH)
170 {
171 if (raster_in->rasterdata[COLORTYPE_COLOR])
172 {
173 if (vip) // RGB values interleaved
174 {
175 unsigned int width = iInputWidth*3;
176 for (unsigned int i=0; i < width; i += 3)
177 {
178 unsigned int factor = ifactor;
179 if (rem >= 1000)
180 {
181 factor++;
182 rem -= 1000;
183 }
184 for (unsigned int j=0; j < factor; j++)
185 {
186 pOutputBuffer[COLORTYPE_COLOR][targptr++] = raster_in->rasterdata[COLORTYPE_COLOR][i];
187 pOutputBuffer[COLORTYPE_COLOR][targptr++] = raster_in->rasterdata[COLORTYPE_COLOR][i+1];
188 pOutputBuffer[COLORTYPE_COLOR][targptr++] = raster_in->rasterdata[COLORTYPE_COLOR][i+2];
189 }
190 rem += remainder;
191 }
192 }
193 else // KCMY values NOT interleaved
194 // iInputWidth = bytes per plane
195 for (unsigned int i=0; i < NumInks; i++) // loop over planes
196 {
197 unsigned int planecount=0; // count output bytes for this plane
198 unsigned int src=0; // count input bytes for this plane
199 while ((planecount < iOutputWidth-1) && (src < iInputWidth))
200 {
201 unsigned int factor = ifactor;
202 if (rem >= 1000)
203 {
204 factor++;
205 rem -= 1000;
206 }
207 for (unsigned int j=0; (j < factor) && (planecount < iOutputWidth-1); j++)
208 {
209 pOutputBuffer[COLORTYPE_COLOR][targptr++] = raster_in->rasterdata[COLORTYPE_COLOR][sourceptr];
210 planecount++;
211 }
212 rem += remainder;
213 sourceptr++; src++;
214 }
215 while (planecount < iOutputWidth-1) // fill out odd bytes so all planes are equal
216 {
217 pOutputBuffer[COLORTYPE_COLOR][targptr++] = raster_in->rasterdata[COLORTYPE_COLOR][sourceptr-1];
218 planecount++;
219 }
220
221 }
222 }
223 }
224
225 ifactor = (unsigned int) (int) ScaleFactor;
226 targptr=0;
227 sourceptr=0;
228 rem = remainder;
229
230 if (myplane == COLORTYPE_BLACK || myplane == COLORTYPE_BOTH)
231 {
232 if (raster_in->rasterdata[COLORTYPE_BLACK])
233 {
234 // K values NOT interleaved
235 // iInputWidth = bytes per plane
236 unsigned int planecount=0; // count output bytes for this plane
237 unsigned int src=0; // count input bytes for this plane
238 while ((planecount < iOutputWidth-1) && (src < iInputWidth))
239 {
240 unsigned int factor = ifactor;
241 if (rem >= 1000)
242 {
243 factor++;
244 rem -= 1000;
245 }
246 for (unsigned int j=0; (j < factor) && (planecount < iOutputWidth-1); j++)
247 {
248 pOutputBuffer[COLORTYPE_BLACK][targptr++] = raster_in->rasterdata[COLORTYPE_BLACK][sourceptr];
249 planecount++;
250 }
251 rem += remainder;
252 sourceptr++; src++;
253 }
254 while (planecount < iOutputWidth-1) // fill out odd bytes so all planes are equal
255 {
256 pOutputBuffer[COLORTYPE_BLACK][targptr++] = raster_in->rasterdata[COLORTYPE_BLACK][sourceptr-1];
257 planecount++;
258 }
259 }
260 }
261
262 unsigned int factor = ifactor;
263 if (rowremainder >= 1000)
264 {
265 factor++;
266 rowremainder -= 1000;
267 }
268 if (myplane == COLORTYPE_BLACK && raster_in->rasterdata[COLORTYPE_COLOR])
269 iRastersReady = 1;
270 else
271 iRastersReady=factor;
272 iRastersDelivered=0;
273 rowremainder += remainder;
274 return true;
275 }
276
NextOutputRaster(RASTERDATA & next_raster)277 bool Scaler::NextOutputRaster(RASTERDATA &next_raster)
278 {
279 if (iRastersReady == 0)
280 return false;
281
282 if (myplane == COLORTYPE_BLACK)
283 {
284 if (raster.rasterdata[COLORTYPE_BLACK] == NULL)
285 iRastersReady = 1;
286 }
287 if (myplane == COLORTYPE_COLOR)
288 {
289 iRastersReady--;
290 iRastersDelivered++;
291 }
292 bool bval = false;
293 if (raster.rastersize[COLORTYPE_BLACK] > 0)
294 {
295 next_raster.rastersize[COLORTYPE_BLACK] = raster.rastersize[COLORTYPE_BLACK];
296 next_raster.rasterdata[COLORTYPE_BLACK] = pOutputBuffer[COLORTYPE_BLACK];
297 bval = true;
298 }
299 else
300 {
301 next_raster.rastersize[COLORTYPE_BLACK] = 0;
302 next_raster.rasterdata[COLORTYPE_BLACK] = NULL;
303 }
304 if (raster.rastersize[COLORTYPE_COLOR] > 0)
305 {
306 next_raster.rastersize[COLORTYPE_COLOR] = raster.rastersize[COLORTYPE_COLOR];
307 next_raster.rasterdata[COLORTYPE_COLOR] = pOutputBuffer[COLORTYPE_COLOR];
308 bval = true;
309 }
310 else
311 {
312 next_raster.rastersize[COLORTYPE_COLOR] = 0;
313 next_raster.rasterdata[COLORTYPE_COLOR] = NULL;
314 }
315 return bval;
316 }
317
318