corrade-vassal – Blame information for rev 1

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 vero 1 /// <summary>**************************************************************************
2 ///
3 /// $Id: Resampler.java,v 1.2 2002/08/08 14:07:31 grosbois Exp $
4 ///
5 /// Copyright Eastman Kodak Company, 343 State Street, Rochester, NY 14650
6 /// $Date $
7 /// ***************************************************************************
8 /// </summary>
9 using System;
10 using CSJ2K.j2k.util;
11 using CSJ2K.j2k.image;
12 namespace CSJ2K.Color
13 {
14  
15 /// <summary> This class resamples the components of an image so that
16 /// all have the same number of samples. The current implementation
17 /// only handles the case of 2:1 upsampling.
18 ///
19 /// </summary>
20 /// <seealso cref="jj2000.j2k.colorspace.ColorSpace">
21 /// </seealso>
22 /// <version> 1.0
23 /// </version>
24 /// <author> Bruce A. Kern
25 /// </author>
26 public class Resampler:ColorSpaceMapper
27 {
28 //UPGRADE_NOTE: Final was removed from the declaration of 'minCompSubsX '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
29 private int minCompSubsX;
30 //UPGRADE_NOTE: Final was removed from the declaration of 'minCompSubsY '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
31 private int minCompSubsY;
32 //UPGRADE_NOTE: Final was removed from the declaration of 'maxCompSubsX '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
33 private int maxCompSubsX;
34 //UPGRADE_NOTE: Final was removed from the declaration of 'maxCompSubsY '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
35 private int maxCompSubsY;
36  
37 //UPGRADE_NOTE: Final was removed from the declaration of 'wspan '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
38 //UPGRADE_NOTE: Final was removed from the declaration of 'hspan '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
39 internal int wspan = 0;
40 internal int hspan = 0;
41  
42 /// <summary> Factory method for creating instances of this class.</summary>
43 /// <param name="src">-- source of image data
44 /// </param>
45 /// <param name="csMap">-- provides colorspace info
46 /// </param>
47 /// <returns> Resampler instance
48 /// </returns>
49 public static new BlkImgDataSrc createInstance(BlkImgDataSrc src, ColorSpace csMap)
50 {
51 return new Resampler(src, csMap);
52 }
53  
54 /// <summary> Ctor resamples a BlkImgDataSrc so that all components
55 /// have the same number of samples.
56 ///
57 /// Note the present implementation does only two to one
58 /// respampling in either direction (row, column).
59 ///
60 /// </summary>
61 /// <param name="src">-- Source of image data
62 /// </param>
63 /// <param name="csm">-- provides colorspace info
64 /// </param>
65 protected internal Resampler(BlkImgDataSrc src, ColorSpace csMap):base(src, csMap)
66 {
67  
68 int c;
69  
70 // Calculate the minimum and maximum subsampling factor
71 // across all channels.
72  
73 int minX = src.getCompSubsX(0);
74 int minY = src.getCompSubsY(0);
75 int maxX = minX;
76 int maxY = minY;
77  
78 for (c = 1; c < ncomps; ++c)
79 {
80 minX = System.Math.Min(minX, src.getCompSubsX(c));
81 minY = System.Math.Min(minY, src.getCompSubsY(c));
82 maxX = System.Math.Max(maxX, src.getCompSubsX(c));
83 maxY = System.Math.Max(maxY, src.getCompSubsY(c));
84 }
85  
86 // Throw an exception for other than 2:1 sampling.
87 if ((maxX != 1 && maxX != 2) || (maxY != 1 && maxY != 2))
88 {
89 throw new ColorSpaceException("Upsampling by other than 2:1 not" + " supported");
90 }
91  
92 minCompSubsX = minX;
93 minCompSubsY = minY;
94 maxCompSubsX = maxX;
95 maxCompSubsY = maxY;
96  
97 /* end Resampler ctor */
98 }
99  
100 /// <summary> Return a DataBlk containing the requested component
101 /// upsampled by the scale factor applied to the particular
102 /// scaling direction
103 ///
104 /// Returns, in the blk argument, a block of image data containing the
105 /// specifed rectangular area, in the specified component. The data is
106 /// returned, as a copy of the internal data, therefore the returned data
107 /// can be modified "in place".
108 ///
109 /// <P>The rectangular area to return is specified by the 'ulx', 'uly', 'w'
110 /// and 'h' members of the 'blk' argument, relative to the current
111 /// tile. These members are not modified by this method. The 'offset' of
112 /// the returned data is 0, and the 'scanw' is the same as the block's
113 /// width. See the 'DataBlk' class.
114 ///
115 /// <P>If the data array in 'blk' is 'null', then a new one is created. If
116 /// the data array is not 'null' then it is reused, and it must be large
117 /// enough to contain the block's data. Otherwise an 'ArrayStoreException'
118 /// or an 'IndexOutOfBoundsException' is thrown by the Java system.
119 ///
120 /// <P>The returned data has its 'progressive' attribute set to that of the
121 /// input data.
122 ///
123 /// </summary>
124 /// <param name="blk">Its coordinates and dimensions specify the area to
125 /// return. If it contains a non-null data array, then it must have the
126 /// correct dimensions. If it contains a null data array a new one is
127 /// created. The fields in this object are modified to return the data.
128 ///
129 /// </param>
130 /// <param name="c">The index of the component from which to get the data. Only 0
131 /// and 3 are valid.
132 ///
133 /// </param>
134 /// <returns> The requested DataBlk
135 ///
136 /// </returns>
137 /// <seealso cref="getCompData">
138 /// </seealso>
139 public override DataBlk getInternCompData(DataBlk outblk, int c)
140 {
141  
142 // If the scaling factor of this channel is 1 in both
143 // directions, simply return the source DataBlk.
144  
145 if (src.getCompSubsX(c) == 1 && src.getCompSubsY(c) == 1)
146 return src.getInternCompData(outblk, c);
147  
148 int wfactor = src.getCompSubsX(c);
149 int hfactor = src.getCompSubsY(c);
150 if ((wfactor != 2 && wfactor != 1) || (hfactor != 2 && hfactor != 1))
151 throw new System.ArgumentException("Upsampling by other than 2:1" + " not supported");
152  
153 int leftedgeOut = - 1; // offset to the start of the output scanline
154 int rightedgeOut = - 1; // offset to the end of the output
155 // scanline + 1
156 int leftedgeIn = - 1; // offset to the start of the input scanline
157 int rightedgeIn = - 1; // offset to the end of the input scanline + 1
158  
159  
160 int y0In, y1In, y0Out, y1Out;
161 int x0In, x1In, x0Out, x1Out;
162  
163 y0Out = outblk.uly;
164 y1Out = y0Out + outblk.h - 1;
165  
166 x0Out = outblk.ulx;
167 x1Out = x0Out + outblk.w - 1;
168  
169 y0In = y0Out / hfactor;
170 y1In = y1Out / hfactor;
171  
172 x0In = x0Out / wfactor;
173 x1In = x1Out / wfactor;
174  
175  
176 // Calculate the requested height and width, requesting an extra
177 // row and or for upsampled channels.
178 int reqW = x1In - x0In + 1;
179 int reqH = y1In - y0In + 1;
180  
181 // Initialize general input and output indexes
182 int kOut = - 1;
183 int kIn = - 1;
184 int yIn;
185  
186 switch (outblk.DataType)
187 {
188  
189  
190 case DataBlk.TYPE_INT:
191  
192 DataBlkInt inblkInt = new DataBlkInt(x0In, y0In, reqW, reqH);
193 inblkInt = (DataBlkInt) src.getInternCompData(inblkInt, c);
194 dataInt[c] = inblkInt.DataInt;
195  
196 // Reference the working array
197 int[] outdataInt = (int[]) outblk.Data;
198  
199 // Create data array if necessary
200 if (outdataInt == null || outdataInt.Length != outblk.w * outblk.h)
201 {
202 outdataInt = new int[outblk.h * outblk.w];
203 outblk.Data = outdataInt;
204 }
205  
206 // The nitty-gritty.
207  
208 for (int yOut = y0Out; yOut <= y1Out; ++yOut)
209 {
210  
211 yIn = yOut / hfactor;
212  
213  
214 leftedgeIn = inblkInt.offset + (yIn - y0In) * inblkInt.scanw;
215 rightedgeIn = leftedgeIn + inblkInt.w;
216 leftedgeOut = outblk.offset + (yOut - y0Out) * outblk.scanw;
217 rightedgeOut = leftedgeOut + outblk.w;
218  
219 kIn = leftedgeIn;
220 kOut = leftedgeOut;
221  
222 if ((x0Out & 0x1) == 1)
223 {
224 // first is odd do the pixel once.
225 outdataInt[kOut++] = dataInt[c][kIn++];
226 }
227  
228 if ((x1Out & 0x1) == 0)
229 {
230 // last is even adjust loop bounds
231 rightedgeOut--;
232 }
233  
234 while (kOut < rightedgeOut)
235 {
236 outdataInt[kOut++] = dataInt[c][kIn];
237 outdataInt[kOut++] = dataInt[c][kIn++];
238 }
239  
240 if ((x1Out & 0x1) == 0)
241 {
242 // last is even do the pixel once.
243 outdataInt[kOut++] = dataInt[c][kIn];
244 }
245 }
246  
247 outblk.progressive = inblkInt.progressive;
248 break;
249  
250  
251 case DataBlk.TYPE_FLOAT:
252  
253 DataBlkFloat inblkFloat = new DataBlkFloat(x0In, y0In, reqW, reqH);
254 inblkFloat = (DataBlkFloat) src.getInternCompData(inblkFloat, c);
255 dataFloat[c] = inblkFloat.DataFloat;
256  
257 // Reference the working array
258 float[] outdataFloat = (float[]) outblk.Data;
259  
260 // Create data array if necessary
261 if (outdataFloat == null || outdataFloat.Length != outblk.w * outblk.h)
262 {
263 outdataFloat = new float[outblk.h * outblk.w];
264 outblk.Data = outdataFloat;
265 }
266  
267 // The nitty-gritty.
268  
269 for (int yOut = y0Out; yOut <= y1Out; ++yOut)
270 {
271  
272 yIn = yOut / hfactor;
273  
274  
275 leftedgeIn = inblkFloat.offset + (yIn - y0In) * inblkFloat.scanw;
276 rightedgeIn = leftedgeIn + inblkFloat.w;
277 leftedgeOut = outblk.offset + (yOut - y0Out) * outblk.scanw;
278 rightedgeOut = leftedgeOut + outblk.w;
279  
280 kIn = leftedgeIn;
281 kOut = leftedgeOut;
282  
283 if ((x0Out & 0x1) == 1)
284 {
285 // first is odd do the pixel once.
286 outdataFloat[kOut++] = dataFloat[c][kIn++];
287 }
288  
289 if ((x1Out & 0x1) == 0)
290 {
291 // last is even adjust loop bounds
292 rightedgeOut--;
293 }
294  
295 while (kOut < rightedgeOut)
296 {
297 outdataFloat[kOut++] = dataFloat[c][kIn];
298 outdataFloat[kOut++] = dataFloat[c][kIn++];
299 }
300  
301 if ((x1Out & 0x1) == 0)
302 {
303 // last is even do the pixel once.
304 outdataFloat[kOut++] = dataFloat[c][kIn];
305 }
306 }
307  
308 outblk.progressive = inblkFloat.progressive;
309 break;
310  
311  
312 case DataBlk.TYPE_SHORT:
313 case DataBlk.TYPE_BYTE:
314 default:
315 // Unsupported output type.
316 throw new System.ArgumentException("invalid source datablock " + "type");
317 }
318  
319 return outblk;
320 }
321  
322  
323 /// <summary> Return an appropriate String representation of this Resampler instance.</summary>
324 public override System.String ToString()
325 {
326 System.Text.StringBuilder rep = new System.Text.StringBuilder("[Resampler: ncomps= " + ncomps);
327 System.Text.StringBuilder body = new System.Text.StringBuilder(" ");
328 for (int i = 0; i < ncomps; ++i)
329 {
330 body.Append(eol);
331 body.Append("comp[");
332 body.Append(i);
333 body.Append("] xscale= ");
334 body.Append(imgdatasrc.getCompSubsX(i));
335 body.Append(", yscale= ");
336 body.Append(imgdatasrc.getCompSubsY(i));
337 }
338  
339 rep.Append(ColorSpace.indent(" ", body));
340 return rep.Append("]").ToString();
341 }
342  
343  
344  
345 /// <summary> Returns, in the blk argument, a block of image data containing the
346 /// specifed rectangular area, in the specified component. The data is
347 /// returned, as a copy of the internal data, therefore the returned data
348 /// can be modified "in place".
349 ///
350 /// <P>The rectangular area to return is specified by the 'ulx', 'uly', 'w'
351 /// and 'h' members of the 'blk' argument, relative to the current
352 /// tile. These members are not modified by this method. The 'offset' of
353 /// the returned data is 0, and the 'scanw' is the same as the block's
354 /// width. See the 'DataBlk' class.
355 ///
356 /// <P>If the data array in 'blk' is 'null', then a new one is created. If
357 /// the data array is not 'null' then it is reused, and it must be large
358 /// enough to contain the block's data. Otherwise an 'ArrayStoreException'
359 /// or an 'IndexOutOfBoundsException' is thrown by the Java system.
360 ///
361 /// <P>The returned data has its 'progressive' attribute set to that of the
362 /// input data.
363 ///
364 /// </summary>
365 /// <param name="blk">Its coordinates and dimensions specify the area to
366 /// return. If it contains a non-null data array, then it must have the
367 /// correct dimensions. If it contains a null data array a new one is
368 /// created. The fields in this object are modified to return the data.
369 ///
370 /// </param>
371 /// <param name="c">The index of the component from which to get the data. Only 0
372 /// and 3 are valid.
373 ///
374 /// </param>
375 /// <returns> The requested DataBlk
376 ///
377 /// </returns>
378 /// <seealso cref="getInternCompData">
379 ///
380 /// </seealso>
381 public override DataBlk getCompData(DataBlk outblk, int c)
382 {
383 return getInternCompData(outblk, c);
384 }
385  
386  
387 /// <summary> Returns the height in pixels of the specified component in the
388 /// overall image.
389 /// </summary>
390 public override int getCompImgHeight(int c)
391 {
392 return src.getCompImgHeight(c) * src.getCompSubsY(c);
393 }
394  
395 /// <summary> Returns the width in pixels of the specified component in the
396 /// overall image.
397 /// </summary>
398 public override int getCompImgWidth(int c)
399 {
400 return src.getCompImgWidth(c) * src.getCompSubsX(c);
401 }
402  
403 /// <summary> Returns the component subsampling factor in the horizontal
404 /// direction, for the specified component.
405 /// </summary>
406 public override int getCompSubsX(int c)
407 {
408 return 1;
409 }
410  
411 /// <summary> Returns the component subsampling factor in the vertical
412 /// direction, for the specified component.
413 /// </summary>
414 public override int getCompSubsY(int c)
415 {
416 return 1;
417 }
418  
419 /// <summary> Returns the height in pixels of the specified tile-component.</summary>
420 public override int getTileCompHeight(int t, int c)
421 {
422 return src.getTileCompHeight(t, c) * src.getCompSubsY(c);
423 }
424  
425 /// <summary> Returns the width in pixels of the specified tile-component..</summary>
426 public override int getTileCompWidth(int t, int c)
427 {
428 return src.getTileCompWidth(t, c) * src.getCompSubsX(c);
429 }
430  
431 /* end class Resampler */
432 }
433 }