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