qrdnicapacitor 1.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (31) hide show
  1. package/Package.swift +34 -0
  2. package/Qrdnicapacitor.podspec +18 -0
  3. package/README.md +106 -0
  4. package/android/build.gradle +64 -0
  5. package/android/src/main/AndroidManifest.xml +16 -0
  6. package/android/src/main/java/com/cqesolutions/qrdnicapacitor/QrCodeScanner.java +84 -0
  7. package/android/src/main/java/com/cqesolutions/qrdnicapacitor/jj2000/ImgStreamWriter.java +483 -0
  8. package/android/src/main/java/com/cqesolutions/qrdnicapacitor/jj2000/J2kStreamDecoder.java +116 -0
  9. package/android/src/main/java/com/cqesolutions/qrdnicapacitor/jj2000/MyFileFormatReader.java +204 -0
  10. package/android/src/main/java/com/cqesolutions/qrdnicapacitor/qrdni.java +130 -0
  11. package/android/src/main/java/com/cqesolutions/qrdnicapacitor/qrdniPlugin.java +109 -0
  12. package/android/src/main/res/.gitkeep +0 -0
  13. package/dist/docs.json +255 -0
  14. package/dist/esm/definitions.d.ts +44 -0
  15. package/dist/esm/definitions.js +2 -0
  16. package/dist/esm/definitions.js.map +1 -0
  17. package/dist/esm/index.d.ts +4 -0
  18. package/dist/esm/index.js +7 -0
  19. package/dist/esm/index.js.map +1 -0
  20. package/dist/esm/web.d.ts +14 -0
  21. package/dist/esm/web.js +18 -0
  22. package/dist/esm/web.js.map +1 -0
  23. package/dist/plugin.cjs.js +32 -0
  24. package/dist/plugin.cjs.js.map +1 -0
  25. package/dist/plugin.js +35 -0
  26. package/dist/plugin.js.map +1 -0
  27. package/ios/Sources/qrdniPlugin/ScannerViewController.swift +170 -0
  28. package/ios/Sources/qrdniPlugin/qrdni.swift +111 -0
  29. package/ios/Sources/qrdniPlugin/qrdniPlugin.swift +105 -0
  30. package/ios/Tests/qrdniPluginTests/qrdniTests.swift +15 -0
  31. package/package.json +80 -0
@@ -0,0 +1,483 @@
1
+ /*
2
+ * CVS identifier:
3
+ *
4
+ * $Id: ImgWriterPPM.java,v 1.16 2002/07/25 15:10:14 grosbois Exp $
5
+ *
6
+ * Class: ImgWriterRawPPM
7
+ *
8
+ * Description: Image writer for unsigned 8 bit data in
9
+ * PPM file format.
10
+ *
11
+ *
12
+ *
13
+ * COPYRIGHT:
14
+ *
15
+ * This software module was originally developed by Rapha�l Grosbois and
16
+ * Diego Santa Cruz (Swiss Federal Institute of Technology-EPFL); Joel
17
+ * Askel�f (Ericsson Radio Systems AB); and Bertrand Berthelot, David
18
+ * Bouchard, F�lix Henry, Gerard Mozelle and Patrice Onno (Canon Research
19
+ * Centre France S.A) in the course of development of the JPEG2000
20
+ * standard as specified by ISO/IEC 15444 (JPEG 2000 Standard). This
21
+ * software module is an implementation of a part of the JPEG 2000
22
+ * Standard. Swiss Federal Institute of Technology-EPFL, Ericsson Radio
23
+ * Systems AB and Canon Research Centre France S.A (collectively JJ2000
24
+ * Partners) agree not to assert against ISO/IEC and users of the JPEG
25
+ * 2000 Standard (Users) any of their rights under the copyright, not
26
+ * including other intellectual property rights, for this software module
27
+ * with respect to the usage by ISO/IEC and Users of this software module
28
+ * or modifications thereof for use in hardware or software products
29
+ * claiming conformance to the JPEG 2000 Standard. Those intending to use
30
+ * this software module in hardware or software products are advised that
31
+ * their use may infringe existing patents. The original developers of
32
+ * this software module, JJ2000 Partners and ISO/IEC assume no liability
33
+ * for use of this software module or modifications thereof. No license
34
+ * or right to this software module is granted for non JPEG 2000 Standard
35
+ * conforming products. JJ2000 Partners have full right to use this
36
+ * software module for his/her own purpose, assign or donate this
37
+ * software module to any third party and to inhibit third parties from
38
+ * using this software module for non JPEG 2000 Standard conforming
39
+ * products. This copyright notice must be included in all copies or
40
+ * derivative works of this software module.
41
+ *
42
+ * Copyright (c) 1999/2000 JJ2000 Partners.
43
+ * */
44
+ package com.cqesolutions.qrdnicapacitor.jj2000;
45
+
46
+ import android.graphics.Bitmap;
47
+
48
+ import java.io.ByteArrayInputStream;
49
+ import java.io.IOException;
50
+ import java.io.InputStream;
51
+ import java.nio.ByteBuffer;
52
+ import java.util.Arrays;
53
+
54
+ import jj2000.j2k.image.BlkImgDataSrc;
55
+ import jj2000.j2k.image.DataBlk;
56
+ import jj2000.j2k.image.DataBlkInt;
57
+ import jj2000.j2k.image.output.ImgWriter;
58
+
59
+ /**
60
+ * This class writes 3 components from an image in 8 bit unsigned data to a
61
+ * binary PPM file.
62
+ *
63
+ * <P>The size of the image that is written is the size of the source
64
+ * image. No component subsampling is allowed in any of the components that
65
+ * are written to the file.
66
+ *
67
+ * <P>Before writing, all coefficients are inversly level-shifted and then
68
+ * "saturated" (they are limited * to the nominal dynamic range).<br>
69
+ *
70
+ * <u>Ex:</u> if the nominal range is 0-255, the following algorithm is
71
+ * applied:<br>
72
+ *
73
+ * <tt>if coeff<0, output=0<br>
74
+ *
75
+ * if coeff>255, output=255<br>
76
+ *
77
+ * else output=coeff</tt>
78
+ *
79
+ * The write() methods of an object of this class may not be called
80
+ * concurrently from different threads.
81
+ *
82
+ * <P>NOTE: This class is not thread safe, for reasons of internal buffering.
83
+ * <P>Modified by D Westland so that it creates a Byte[] rather than a file
84
+ * */
85
+ public class ImgStreamWriter extends ImgWriter {
86
+
87
+ /** Value used to inverse level shift. One for each component */
88
+ private int[] levShift = new int[3];
89
+
90
+ /** Where to write the data */
91
+ private final int CAPACITY = 5000000; //big enough for passport jpegs
92
+ private ByteBuffer buffer = ByteBuffer.allocate(CAPACITY);
93
+
94
+ /** The array of indexes of the components from where to get the data */
95
+ private int cps[] = new int[3];
96
+
97
+ /** The array of the number of fractional bits in the components of the
98
+ source data */
99
+ private int fb[] = new int[3];
100
+
101
+ /** A DataBlk, just used to avoid allocating a new one each time
102
+ it is needed */
103
+ private DataBlkInt db = new DataBlkInt();
104
+
105
+ /** The offset of the raw pixel data in the PPM file */
106
+ private int offset;
107
+
108
+ /** The line buffer. */
109
+ // This makes the class not thrad safe
110
+ // (but it is not the only one making it so)
111
+ private byte buf[];
112
+
113
+ /**
114
+ * Creates a new writer to the specified File object, to write data from
115
+ * the specified component.
116
+ *
117
+ * <p>The three components that will be written as R, G and B must be
118
+ * specified through the b1, b2 and b3 arguments.</p>
119
+ *
120
+ *
121
+ * @param imgSrc The source from where to get the image data to write.
122
+ *
123
+ * @param n1 The index of the first component from where to get the data,
124
+ * that will be written as the red channel.
125
+ *
126
+ * @param n2 The index of the second component from where to get the data,
127
+ * that will be written as the green channel.
128
+ *
129
+ * @param n3 The index of the third component from where to get the data,
130
+ * that will be written as the green channel.
131
+ *
132
+ * @see DataBlk
133
+ * */
134
+ public ImgStreamWriter(BlkImgDataSrc imgSrc,
135
+ int n1,int n2,int n3) throws IOException {
136
+ // Check that imgSrc is of the correct type
137
+ // Check that the component index is valid
138
+ if((n1<0) || (n1>=imgSrc.getNumComps()) ||
139
+ (n2<0) || (n2>=imgSrc.getNumComps()) ||
140
+ (n3<0) || (n3>=imgSrc.getNumComps()) ||
141
+ (imgSrc.getNomRangeBits(n1)>8) ||
142
+ (imgSrc.getNomRangeBits(n2)>8) ||
143
+ (imgSrc.getNomRangeBits(n3)>8)) {
144
+ //throw new IllegalArgumentException("Invalid component indexes");
145
+ // In case of Invalid component indexes, lets try with 0,0,0
146
+ if(n1>=imgSrc.getNumComps())
147
+ n1=0;
148
+ if(n2>=imgSrc.getNumComps())
149
+ n2=0;
150
+ if(n3>=imgSrc.getNumComps())
151
+ n3=0;
152
+ }
153
+ // Initialize
154
+ w = imgSrc.getCompImgWidth(n1);
155
+ h = imgSrc.getCompImgHeight(n1);
156
+ // Check that all components have same width and height
157
+ if(w!=imgSrc.getCompImgWidth(n2) ||
158
+ w!=imgSrc.getCompImgWidth(n3) ||
159
+ h!=imgSrc.getCompImgHeight(n2) ||
160
+ h!=imgSrc.getCompImgHeight(n3)) {
161
+ throw new IllegalArgumentException("All components must have the"+
162
+ " same dimensions and no"+
163
+ " subsampling");
164
+ }
165
+ w = imgSrc.getImgWidth();
166
+ h = imgSrc.getImgHeight();
167
+
168
+ // Continue initialization
169
+ buffer.clear();
170
+
171
+ src = imgSrc;
172
+ cps[0] = n1;
173
+ cps[1] = n2;
174
+ cps[2] = n3;
175
+ fb[0] = imgSrc.getFixedPoint(n1);
176
+ fb[1] = imgSrc.getFixedPoint(n2);
177
+ fb[2] = imgSrc.getFixedPoint(n3);
178
+
179
+ levShift[0] = 1<< (imgSrc.getNomRangeBits(n1)-1);
180
+ levShift[1] = 1<< (imgSrc.getNomRangeBits(n2)-1);
181
+ levShift[2] = 1<< (imgSrc.getNomRangeBits(n3)-1);
182
+
183
+ writeHeaderInfo();
184
+ }
185
+
186
+
187
+ /**
188
+ * Closes the underlying file or network connection to where the data is
189
+ * written. Any call to other methods of the class become illegal after a
190
+ * call to this one.
191
+ *
192
+ * @exception IOException If an I/O error occurs.
193
+ * */
194
+ public void close() throws IOException {
195
+ src = null;
196
+ db = null;
197
+ }
198
+
199
+ /**
200
+ * Writes all buffered data to the file or resource.
201
+ *
202
+ * @exception IOException If an I/O error occurs.
203
+ * */
204
+ public void flush() throws IOException {
205
+ // No flush needed here since we are using a RandomAccessFile Get rid
206
+ // of line buffer (is this a good choice?)
207
+ buf = null;
208
+ }
209
+
210
+ /**
211
+ * Writes the data of the specified area to the file, coordinates are
212
+ * relative to the current tile of the source. Before writing, the
213
+ * coefficients are limited to the nominal range.
214
+ *
215
+ * <p>This method may not be called concurrently from different
216
+ * threads.</p>
217
+ *
218
+ * <p>If the data returned from the BlkImgDataSrc source is progressive,
219
+ * then it is requested over and over until it is not progressive
220
+ * anymore.</p>
221
+ *
222
+ * @param ulx The horizontal coordinate of the upper-left corner of the
223
+ * area to write, relative to the current tile.
224
+ *
225
+ * @param uly The vertical coordinate of the upper-left corner of the area
226
+ * to write, relative to the current tile.
227
+ *
228
+ * @param w The width of the area to write.
229
+ *
230
+ * @param h The height of the area to write.
231
+ *
232
+ * @exception IOException If an I/O error occurs.
233
+ * */
234
+ public void write(int ulx, int uly, int w, int h) throws IOException {
235
+ int k,j,i,c;
236
+ // In local variables for faster access
237
+ int fracbits;
238
+ // variables used during coeff saturation
239
+ int shift,tmp,maxVal;
240
+ int tOffx, tOffy; // Active tile offset in the X and Y direction
241
+
242
+ // Active tiles in all components have same offset since they are at
243
+ // same resolution (PPM does not support anything else)
244
+ tOffx = src.getCompULX(cps[0]) -
245
+ (int)Math.ceil(src.getImgULX()/(double)src.getCompSubsX(cps[0]));
246
+ tOffy = src.getCompULY(cps[0]) -
247
+ (int)Math.ceil(src.getImgULY()/(double)src.getCompSubsY(cps[0]));
248
+
249
+ // Check the array size
250
+ if(db.data!=null && db.data.length<w) {
251
+ // A new one will be allocated by getInternCompData()
252
+ db.data = null;
253
+ }
254
+
255
+ // Check the line buffer
256
+ if(buf==null || buf.length<3*w) {
257
+ buf = new byte[3*w];
258
+ }
259
+
260
+ // Write the data to the file
261
+ // Write line by line
262
+ for(i=0; i<h; i++) {
263
+ // Write into buffer first loop over the three components and
264
+ // write for each
265
+ for(c=0; c<3; c++) {
266
+ maxVal= (1<<src.getNomRangeBits(cps[c]))-1;
267
+ shift = levShift[c];
268
+
269
+ // Initialize db
270
+ db.ulx = ulx;
271
+ db.uly = uly+i;
272
+ db.w = w;
273
+ db.h = 1;
274
+
275
+ // Request the data and make sure it is not progressive
276
+ do {
277
+ db = (DataBlkInt)src.getInternCompData(db,cps[c]);
278
+ } while (db.progressive);
279
+ // Get the fracbits value
280
+ fracbits = fb[c];
281
+ // Write all bytes in the line
282
+ if(fracbits==0) {
283
+ for(k=db.offset+w-1, j=3*w-1+c-2; j>=0; k--) {
284
+ tmp = db.data[k]+shift;
285
+ buf[j] = (byte)((tmp<0)? 0 : ((tmp>maxVal)?
286
+ maxVal : tmp));
287
+ j -= 3;
288
+ }
289
+ } else {
290
+ for(k=db.offset+w-1, j=3*w-1+c-2; j>=0; k--) {
291
+ tmp = (db.data[k]>>>fracbits)+shift;
292
+ buf[j] = (byte)((tmp<0)? 0 : ((tmp>maxVal)?
293
+ maxVal : tmp));
294
+ j -= 3;
295
+ }
296
+ }
297
+ }
298
+ // Write buffer into file
299
+ int psn = offset+3*(this.w*(uly+tOffy+i)+ulx+tOffx);
300
+ buffer.position(psn);
301
+ buffer.put(buf, 0, 3*w);
302
+ }
303
+ }
304
+
305
+ /**
306
+ * Writes the source's current tile to the output. The requests of data
307
+ * issued to the source BlkImgDataSrc object are done by strips, in order
308
+ * to reduce memory usage.
309
+ *
310
+ * <P>If the data returned from the BlkImgDataSrc source is progressive,
311
+ * then it is requested over and over until it is not progressive any
312
+ * more.
313
+ *
314
+ * @exception IOException If an I/O error occurs.
315
+ * */
316
+ public void write() throws IOException {
317
+ int i;
318
+ int tIdx = src.getTileIdx();
319
+ int tw = src.getTileCompWidth(tIdx,0); // Tile width
320
+ int th = src.getTileCompHeight(tIdx, 0); // Tile height
321
+ // Write in strips
322
+ for(i=0; i<th ; i+=DEF_STRIP_HEIGHT) {
323
+ write(0,i,tw,((th-i)<DEF_STRIP_HEIGHT) ? th-i : DEF_STRIP_HEIGHT);
324
+ }
325
+ }
326
+
327
+ /**
328
+ * Writes the header info of the PPM file :
329
+ *
330
+ * P6<br>
331
+ *
332
+ * width height<br>
333
+ *
334
+ * 255<br>
335
+ *
336
+ * @exception IOException If there is an I/O Error
337
+ * */
338
+ private void writeHeaderInfo() throws IOException {
339
+ byte[] byteVals;
340
+ int i;
341
+ String val;
342
+
343
+ // write 'P6' to file
344
+ buffer.position(0);
345
+ buffer.put((byte) 80);
346
+ buffer.put((byte) 54);
347
+ buffer.put((byte) 10);
348
+ offset=3;
349
+ // Write width in ASCII
350
+ val=String.valueOf(w);
351
+ byteVals=val.getBytes();
352
+ for(i=0;i<byteVals.length;i++) {
353
+ buffer.put(byteVals[i]);
354
+ offset++;
355
+ }
356
+ buffer.put((byte)32);
357
+ offset++;
358
+ // Write height in ASCII
359
+ val=String.valueOf(h);
360
+ byteVals=val.getBytes();
361
+ for(i=0;i<byteVals.length;i++) {
362
+ buffer.put(byteVals[i]);
363
+ offset++;
364
+ }
365
+
366
+ buffer.put((byte)10);
367
+ buffer.put((byte)50);
368
+ buffer.put((byte)53);
369
+ buffer.put((byte)53);
370
+ buffer.put((byte)10);
371
+ offset+=5;
372
+ }
373
+
374
+ public ByteArrayInputStream getByteArrayInputStream() {
375
+ //buffer.flip();
376
+ byte[] contents = Arrays.copyOf( buffer.array(), buffer.position());
377
+ return new ByteArrayInputStream(contents);
378
+ }
379
+
380
+ public Bitmap getImage() throws IOException {
381
+ writeAll();
382
+ byte[] contents = Arrays.copyOf( buffer.array(), buffer.position());
383
+ PPMConverter ppmc = new PPMConverter(new ByteArrayInputStream(contents));
384
+ return ppmc.createBufferedImage();
385
+ }
386
+ /**
387
+ * Returns a string of information about the object, more than 1 line
388
+ * long. The information string includes information from the underlying
389
+ * RandomAccessFile (its toString() method is called in turn).
390
+ *
391
+ * @return A string of information about the object.
392
+ * */
393
+ public String toString() {
394
+ return "ImgWriterPPM: WxH = " + w + "x" + h + ", Components = " +
395
+ cps[0]+","+cps[1]+","+cps[2]+ "\nUnderlying RandomAccessFile:\n";
396
+ }
397
+ private class PPMConverter {
398
+ /**
399
+ * Converts a .ppm file into an android bitmap
400
+ *
401
+ * @author duncan
402
+ *
403
+ */
404
+
405
+ InputStream is;
406
+
407
+ private PPMConverter(InputStream is) {
408
+ this.is = is;
409
+ }
410
+
411
+ //public BufferedImage createBufferedImage() throws IOException {
412
+ public Bitmap createBufferedImage() throws IOException {
413
+
414
+ if (!readUntilWhiteSpace(is).equals("P6")) throw new IOException();
415
+ int width = Integer.parseInt(readUntilWhiteSpace(is));
416
+ int height = Integer.parseInt(readUntilWhiteSpace(is));
417
+ int depth = Integer.parseInt(readUntilWhiteSpace(is));
418
+ if (depth!=0xFF) throw new IOException("This decoder only accepts 8-bit image depth");
419
+ //BufferedImage img = new BufferedImage(width, height, BufferedImage.TYPE_3BYTE_BGR);
420
+ Bitmap img = Bitmap.createBitmap(width, height,Bitmap.Config.ARGB_8888);
421
+ //WritableRaster raster = img.getRaster();
422
+ int[] pixel = new int[3];
423
+ // Read in the pixels
424
+ for (int y = 0; y < height; y++) {
425
+ for (int x = 0; x < width; x++) {
426
+ int red = is.read();
427
+ int green = is.read();
428
+ int blue = is.read();
429
+ if (red>255 || red<0) {
430
+ //Log.e(DEBUG,"Red out of range");
431
+ throw new IOException();
432
+ }
433
+ if (green>255 || green<0) {
434
+ //Log.e(DEBUG,"Green out of range");
435
+ throw new IOException();
436
+ }
437
+ if (blue>255 || blue<0) {
438
+ //Log.e(DEBUG,"Blue out of range");
439
+ throw new IOException();
440
+ }
441
+ pixel[0]=red;
442
+ pixel[1]=green;
443
+ pixel[2]=blue;
444
+ //raster.setPixel(x, y, pixel);
445
+ img.setPixel(x, y, getIntFromColor(pixel[0],pixel[1],pixel[2]));
446
+ }
447
+ }
448
+ return img;
449
+ }
450
+
451
+ public int getIntFromColor(int Red, int Green, int Blue){
452
+ Red = (Red << 16) & 0x00FF0000; //Shift red 16-bits and mask out other stuff
453
+ Green = (Green << 8) & 0x0000FF00; //Shift Green 8-bits and mask out other stuff
454
+ Blue = Blue & 0x000000FF; //Mask out anything not blue.
455
+
456
+ return 0xFF000000 | Red | Green | Blue; //0xFF000000 for 100% Alpha. Bitwise OR everything together.
457
+ }
458
+
459
+
460
+ /**
461
+ * Read characters until whitespace is encountered, then returns a string
462
+ * DOES NOT CHECK FOR EOF
463
+ * @return
464
+ * @throws IOException
465
+ */
466
+ public String readUntilWhiteSpace(InputStream is) throws IOException {
467
+ String data="";
468
+ int b;
469
+ char next = (char) is.read();
470
+ //skip any whitespace
471
+ while(next =='\n' || next ==' ' || next=='\t') {
472
+ next = (char) is.read();
473
+ }
474
+ while(next !='\n' && next !=' ' && next!='\t') {
475
+ data += next;
476
+ b = is.read();
477
+ if (b==-1) throw new IOException("Unexpected EOF while reading header");
478
+ next = (char)b;
479
+ }
480
+ return data;
481
+ }
482
+ }
483
+ }
@@ -0,0 +1,116 @@
1
+ package com.cqesolutions.qrdnicapacitor.jj2000;
2
+
3
+ import android.graphics.Bitmap;
4
+
5
+ import java.io.EOFException;
6
+ import java.io.IOException;
7
+ import java.io.InputStream;
8
+
9
+ import colorspace.ColorSpace;
10
+ import colorspace.ColorSpaceException;
11
+ import icc.ICCProfileException;
12
+ import jj2000.j2k.codestream.HeaderInfo;
13
+ import jj2000.j2k.codestream.reader.BitstreamReaderAgent;
14
+ import jj2000.j2k.codestream.reader.HeaderDecoder;
15
+ import jj2000.j2k.decoder.Decoder;
16
+ import jj2000.j2k.decoder.DecoderSpecs;
17
+ import jj2000.j2k.entropy.decoder.EntropyDecoder;
18
+ import jj2000.j2k.image.BlkImgDataSrc;
19
+ import jj2000.j2k.image.ImgDataConverter;
20
+ import jj2000.j2k.image.invcomptransf.InvCompTransf;
21
+ import jj2000.j2k.quantization.dequantizer.Dequantizer;
22
+ import jj2000.j2k.roi.ROIDeScaler;
23
+ import jj2000.j2k.util.ISRandomAccessIO;
24
+ import jj2000.j2k.util.ParameterList;
25
+ import jj2000.j2k.wavelet.synthesis.InverseWT;
26
+
27
+ public class J2kStreamDecoder {
28
+
29
+ public J2kStreamDecoder() {
30
+ }
31
+
32
+ public Bitmap decode(InputStream is) throws EOFException, IOException,
33
+ ColorSpaceException, ICCProfileException {
34
+ ISRandomAccessIO in = new ISRandomAccessIO(is);
35
+ ParameterList defpl = new ParameterList();
36
+ String[][] param = Decoder.getAllParameters();
37
+
38
+ for (int i = param.length - 1; i >= 0; i--) {
39
+ if (param[i][3] != null)
40
+ defpl.put(param[i][0], param[i][3]);
41
+ }
42
+ // Create parameter list using defaults
43
+ ParameterList pl = new ParameterList(defpl);
44
+
45
+ // **** File Format ****
46
+ // If the codestream is wrapped in the jp2 fileformat, Read the
47
+ // file format wrapper
48
+ MyFileFormatReader ff = new MyFileFormatReader(in);
49
+ ff.readFileFormat();
50
+ if (ff.JP2FFUsed) {
51
+ in.seek(ff.getFirstCodeStreamPos());
52
+ }
53
+
54
+ // **** header decoder ****
55
+ HeaderInfo hi = new HeaderInfo();
56
+ HeaderDecoder hd = null;
57
+ DecoderSpecs decSpec = null;
58
+ hd = new HeaderDecoder(in, pl, hi);
59
+ decSpec = hd.getDecoderSpecs();
60
+ // Get demixed bitdepths
61
+ int nCompCod = hd.getNumComps();
62
+ int[] depth = new int[nCompCod];
63
+ for (int i = 0; i < nCompCod; i++) {
64
+ depth[i] = hd.getOriginalBitDepth(i);
65
+ }
66
+
67
+ // **** Bit stream reader ****
68
+ BitstreamReaderAgent breader = BitstreamReaderAgent.createInstance(in,
69
+ hd, pl, decSpec, pl.getBooleanParameter("cdstr_info"), hi);
70
+
71
+ // **** Entropy decoder ****
72
+ EntropyDecoder entdec = hd.createEntropyDecoder(breader, pl);
73
+
74
+ // **** ROI de-scaler ****
75
+ ROIDeScaler roids = hd.createROIDeScaler(entdec, pl, decSpec);
76
+
77
+ // **** Dequantizer ****
78
+ Dequantizer deq = hd.createDequantizer(roids, depth, decSpec);
79
+
80
+ // full page inverse wavelet transform
81
+ InverseWT invWT = InverseWT.createInstance(deq, decSpec);
82
+ int res = breader.getImgRes();
83
+ invWT.setImgResLevel(res);
84
+
85
+ // **** Data converter **** (after inverse transform module)
86
+ ImgDataConverter converter = new ImgDataConverter(invWT, 0);
87
+
88
+ // **** Inverse component transformation ****
89
+ InvCompTransf ictransf = new InvCompTransf(converter, decSpec, depth,
90
+ pl);
91
+
92
+ // **** Color space mapping ****
93
+ ColorSpace csMap;
94
+ BlkImgDataSrc color = null;
95
+ BlkImgDataSrc palettized;
96
+ BlkImgDataSrc resampled;
97
+ BlkImgDataSrc channels;
98
+ if (ff.JP2FFUsed && pl.getParameter("nocolorspace").equals("off")) {
99
+ csMap = new ColorSpace(in, hd, pl);
100
+ channels = hd.createChannelDefinitionMapper(ictransf, csMap);
101
+ resampled = hd.createResampler(channels, csMap);
102
+ palettized = hd.createPalettizedColorSpaceMapper(resampled, csMap);
103
+ color = hd.createColorSpaceMapper(palettized, csMap);
104
+ } else { // Skip colorspace mapping
105
+ color = ictransf;
106
+ }
107
+ // This is the last image in the decoding chain
108
+ BlkImgDataSrc decodedImage = color;
109
+ if (color == null) {
110
+ decodedImage = ictransf;
111
+ }
112
+ // write out the image
113
+ ImgStreamWriter imwriter = new ImgStreamWriter(decodedImage, 0, 1, 2);
114
+ return imwriter.getImage();
115
+ }
116
+ }