Source Code Cross Referenced for StdQuantizer.java in  » 6.0-JDK-Modules » Java-Advanced-Imaging » jj2000 » j2k » quantization » quantizer » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » 6.0 JDK Modules » Java Advanced Imaging » jj2000.j2k.quantization.quantizer 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * $RCSfile: StdQuantizer.java,v $
003:         * $Revision: 1.1 $
004:         * $Date: 2005/02/11 05:02:20 $
005:         * $State: Exp $
006:         *
007:         * Class:                   StdQuantizer
008:         *
009:         * Description:             Scalar deadzone quantizer of integer or float
010:         *                          data.
011:         *
012:         *                          Mergerd from StdQuantizerInt and
013:         *                          StdQuantizerFloat from Joel Askelof.
014:         *
015:         *
016:         * COPYRIGHT:
017:         *
018:         * This software module was originally developed by Raphaël Grosbois and
019:         * Diego Santa Cruz (Swiss Federal Institute of Technology-EPFL); Joel
020:         * Askelöf (Ericsson Radio Systems AB); and Bertrand Berthelot, David
021:         * Bouchard, Félix Henry, Gerard Mozelle and Patrice Onno (Canon Research
022:         * Centre France S.A) in the course of development of the JPEG2000
023:         * standard as specified by ISO/IEC 15444 (JPEG 2000 Standard). This
024:         * software module is an implementation of a part of the JPEG 2000
025:         * Standard. Swiss Federal Institute of Technology-EPFL, Ericsson Radio
026:         * Systems AB and Canon Research Centre France S.A (collectively JJ2000
027:         * Partners) agree not to assert against ISO/IEC and users of the JPEG
028:         * 2000 Standard (Users) any of their rights under the copyright, not
029:         * including other intellectual property rights, for this software module
030:         * with respect to the usage by ISO/IEC and Users of this software module
031:         * or modifications thereof for use in hardware or software products
032:         * claiming conformance to the JPEG 2000 Standard. Those intending to use
033:         * this software module in hardware or software products are advised that
034:         * their use may infringe existing patents. The original developers of
035:         * this software module, JJ2000 Partners and ISO/IEC assume no liability
036:         * for use of this software module or modifications thereof. No license
037:         * or right to this software module is granted for non JPEG 2000 Standard
038:         * conforming products. JJ2000 Partners have full right to use this
039:         * software module for his/her own purpose, assign or donate this
040:         * software module to any third party and to inhibit third parties from
041:         * using this software module for non JPEG 2000 Standard conforming
042:         * products. This copyright notice must be included in all copies or
043:         * derivative works of this software module.
044:         *
045:         * Copyright (c) 1999/2000 JJ2000 Partners.
046:         * */
047:        package jj2000.j2k.quantization.quantizer;
048:
049:        import jj2000.j2k.codestream.writer.*;
050:        import jj2000.j2k.wavelet.analysis.*;
051:        import jj2000.j2k.quantization.*;
052:        import jj2000.j2k.wavelet.*;
053:        import jj2000.j2k.image.*;
054:        import jj2000.j2k.*;
055:
056:        import com.sun.media.imageioimpl.plugins.jpeg2000.J2KImageWriteParamJava;
057:
058:        /**
059:         * This class implements scalar quantization of integer or floating-point
060:         * valued source data. The source data is the wavelet transformed image data
061:         * and the output is the quantized wavelet coefficients represented in
062:         * sign-magnitude (see below).
063:         *
064:         * <P>Sign magnitude representation is used (instead of two's complement) for
065:         * the output data. The most significant bit is used for the sign (0 if
066:         * positive, 1 if negative). Then the magnitude of the quantized coefficient
067:         * is stored in the next M most significat bits. The rest of the bits (least
068:         * significant bits) can contain a fractional value of the quantized
069:         * coefficient. This fractional value is not to be coded by the entropy
070:         * coder. However, it can be used to compute rate-distortion measures with
071:         * greater precision.
072:         *
073:         * <P>The value of M is determined for each subband as the sum of the number
074:         * of guard bits G and the nominal range of quantized wavelet coefficients in
075:         * the corresponding subband (Rq), minus 1:
076:         *
077:         * <P>M = G + Rq -1
078:         *
079:         * <P>The value of G should be the same for all subbands. The value of Rq
080:         * depends on the quantization step size, the nominal range of the component
081:         * before the wavelet transform and the analysis gain of the subband (see
082:         * Subband).
083:         *
084:         * <P>The blocks of data that are requested should not cross subband
085:         * boundaries.
086:         *
087:         * @see Subband
088:         *
089:         * @see Quantizer
090:         * */
091:        public class StdQuantizer extends Quantizer {
092:
093:            /** The number of mantissa bits for the quantization steps */
094:            public final static int QSTEP_MANTISSA_BITS = 11;
095:
096:            /** The number of exponent bits for the quantization steps */
097:            // NOTE: formulas in 'convertFromExpMantissa()' and
098:            // 'convertToExpMantissa()' methods do not support more than 5 bits.
099:            public final static int QSTEP_EXPONENT_BITS = 5;
100:
101:            /** The maximum value of the mantissa for the quantization steps */
102:            public final static int QSTEP_MAX_MANTISSA = (1 << QSTEP_MANTISSA_BITS) - 1;
103:
104:            /** The maximum value of the exponent for the quantization steps */
105:            public final static int QSTEP_MAX_EXPONENT = (1 << QSTEP_EXPONENT_BITS) - 1;
106:
107:            /** Natural log of 2, used as a convenience variable */
108:            private static double log2 = Math.log(2);
109:
110:            /** The quantization type specifications */
111:            private QuantTypeSpec qts;
112:
113:            /** The quantization step size specifications */
114:            private QuantStepSizeSpec qsss;
115:
116:            /** The guard bits specifications */
117:            private GuardBitsSpec gbs;
118:
119:            /** The 'CBlkWTDataFloat' object used to request data, used when
120:             * quantizing floating-point data. */
121:            // This variable makes the class thread unsafe, but it avoids allocating
122:            // new objects for code-block that is quantized.
123:            private CBlkWTDataFloat infblk;
124:
125:            /**
126:             * Initializes the source of wavelet transform coefficients. The
127:             * constructor takes information on whether the quantizer is in
128:             * reversible, derived or expounded mode. If the quantizer is reversible
129:             * the value of 'derived' is ignored. If the source data is not integer
130:             * (int) then the quantizer can not be reversible.
131:             *
132:             * <P> After initializing member attributes, getAnSubbandTree is called for
133:             * all components setting the 'stepWMSE' for all subbands in the current
134:             * tile.
135:             *
136:             * @param src The source of wavelet transform coefficients.
137:             *
138:             * @param encSpec The encoder specifications
139:             * */
140:            public StdQuantizer(CBlkWTDataSrc src, J2KImageWriteParamJava wp) {
141:                super (src);
142:                qts = wp.getQuantizationType();
143:                qsss = wp.getQuantizationStep();
144:                gbs = wp.getGuardBits();
145:            }
146:
147:            /**
148:             * Returns the quantization type spec object associated to the quantizer.
149:             *
150:             * @return The quantization type spec
151:             * */
152:            public QuantTypeSpec getQuantTypeSpec() {
153:                return qts;
154:            }
155:
156:            /**
157:             * Returns the number of guard bits used by this quantizer in the given
158:             * tile-component.
159:             *
160:             * @param t Tile index
161:             *
162:             * @param c Component index
163:             *
164:             * @return The number of guard bits
165:             * */
166:            public int getNumGuardBits(int t, int c) {
167:                return ((Integer) gbs.getTileCompVal(t, c)).intValue();
168:            }
169:
170:            /**
171:             * Returns true if the quantized data is reversible, for the specified
172:             * tile-component. For the quantized data to be reversible it is necessary
173:             * and sufficient that the quantization is reversible.
174:             *
175:             * @param t The tile to test for reversibility
176:             *
177:             * @param c The component to test for reversibility
178:             *
179:             * @return True if the quantized data is reversible, false if not.
180:             * */
181:            public boolean isReversible(int t, int c) {
182:                return qts.isReversible(t, c);
183:            }
184:
185:            /**
186:             * Returns true if given tile-component uses derived quantization step
187:             * sizes.
188:             *
189:             * @param t Tile index
190:             *
191:             * @param c Component index
192:             *
193:             * @return True if derived
194:             *
195:             */
196:            public boolean isDerived(int t, int c) {
197:                return qts.isDerived(t, c);
198:            }
199:
200:            /**
201:             * Returns the next code-block in the current tile for the specified
202:             * component, as a copy (see below). The order in which code-blocks are
203:             * returned is not specified. However each code-block is returned only
204:             * once and all code-blocks will be returned if the method is called 'N'
205:             * times, where 'N' is the number of code-blocks in the tile. After all
206:             * the code-blocks have been returned for the current tile calls to this
207:             * method will return 'null'.
208:             *
209:             * <P>When changing the current tile (through 'setTile()' or 'nextTile()')
210:             * this method will always return the first code-block, as if this method
211:             * was never called before for the new current tile.
212:             *
213:             * <P>The data returned by this method is always a copy of the
214:             * data. Therfore it can be modified "in place" without any problems after
215:             * being returned. The 'offset' of the returned data is 0, and the 'scanw'
216:             * is the same as the code-block width. See the 'CBlkWTData' class.
217:             *
218:             * <P>The 'ulx' and 'uly' members of the returned 'CBlkWTData' object
219:             * contain the coordinates of the top-left corner of the block, with
220:             * respect to the tile, not the subband.
221:             *
222:             * @param c The component for which to return the next code-block.
223:             *
224:             * @param cblk If non-null this object will be used to return the new
225:             * code-block. If null a new one will be allocated and returned. If the
226:             * "data" array of the object is non-null it will be reused, if possible,
227:             * to return the data.
228:             *
229:             * @return The next code-block in the current tile for component 'n', or
230:             * null if all code-blocks for the current tile have been returned.
231:             *
232:             * @see CBlkWTData
233:             * */
234:            public CBlkWTData getNextCodeBlock(int c, CBlkWTData cblk) {
235:                return getNextInternCodeBlock(c, cblk);
236:            }
237:
238:            /**
239:             * Returns the next code-block in the current tile for the specified
240:             * component. The order in which code-blocks are returned is not
241:             * specified. However each code-block is returned only once and all
242:             * code-blocks will be returned if the method is called 'N' times, where
243:             * 'N' is the number of code-blocks in the tile. After all the code-blocks
244:             * have been returned for the current tile calls to this method will
245:             * return 'null'.
246:             *
247:             * <P>When changing the current tile (through 'setTile()' or 'nextTile()')
248:             * this method will always return the first code-block, as if this method
249:             * was never called before for the new current tile.
250:             *
251:             * <P>The data returned by this method can be the data in the internal
252:             * buffer of this object, if any, and thus can not be modified by the
253:             * caller. The 'offset' and 'scanw' of the returned data can be
254:             * arbitrary. See the 'CBlkWTData' class.
255:             *
256:             * <P>The 'ulx' and 'uly' members of the returned 'CBlkWTData' object
257:             * contain the coordinates of the top-left corner of the block, with
258:             * respect to the tile, not the subband.
259:             *
260:             * @param c The component for which to return the next code-block.
261:             *
262:             * @param cblk If non-null this object will be used to return the new
263:             * code-block. If null a new one will be allocated and returned. If the
264:             * "data" array of the object is non-null it will be reused, if possible,
265:             * to return the data.
266:             *
267:             * @return The next code-block in the current tile for component 'n', or
268:             * null if all code-blocks for the current tile have been returned.
269:             *
270:             * @see CBlkWTData
271:             * */
272:            public final CBlkWTData getNextInternCodeBlock(int c,
273:                    CBlkWTData cblk) {
274:                // NOTE: this method is declared final since getNextCodeBlock() relies
275:                // on this particular implementation
276:                int k, j;
277:                int tmp, shiftBits, jmin;
278:                int w, h;
279:                int outarr[];
280:                float infarr[] = null;
281:                CBlkWTDataFloat infblk;
282:                float invstep; // The inverse of the quantization step size
283:                boolean intq; // flag for quantizig ints
284:                SubbandAn sb;
285:                float stepUDR; // The quantization step size (for a dynamic
286:                // range of 1, or unit)
287:                int g = ((Integer) gbs.getTileCompVal(tIdx, c)).intValue();
288:
289:                // Are we quantizing ints or floats?
290:                intq = (src.getDataType(tIdx, c) == DataBlk.TYPE_INT);
291:
292:                // Check that we have an output object
293:                if (cblk == null) {
294:                    cblk = new CBlkWTDataInt();
295:                }
296:
297:                // Cache input float code-block
298:                infblk = this .infblk;
299:
300:                // Get data to quantize. When quantizing int data 'cblk' is used to
301:                // get the data to quantize and to return the quantized data as well,
302:                // that's why 'getNextCodeBlock()' is used. This can not be done when
303:                // quantizing float data because of the different data types, that's
304:                // why 'getNextInternCodeBlock()' is used in that case.
305:                if (intq) { // Source data is int
306:                    cblk = src.getNextCodeBlock(c, cblk);
307:                    if (cblk == null) {
308:                        return null; // No more code-blocks in current tile for comp.
309:                    }
310:                    // Input and output arrays are the same (for "in place" quant.)
311:                    outarr = (int[]) cblk.getData();
312:                } else { // Source data is float
313:                    // Can not use 'cblk' to get float data, use 'infblk'
314:                    infblk = (CBlkWTDataFloat) src.getNextInternCodeBlock(c,
315:                            infblk);
316:                    if (infblk == null) {
317:                        // Release buffer from infblk: this enables to garbage collect
318:                        // the big buffer when we are done with last code-block of
319:                        // component.
320:                        this .infblk.setData(null);
321:                        return null; // No more code-blocks in current tile for comp.
322:                    }
323:                    this .infblk = infblk; // Save local cache
324:                    infarr = (float[]) infblk.getData();
325:                    // Get output data array and check that there is memory to put the
326:                    // quantized coeffs in
327:                    outarr = (int[]) cblk.getData();
328:                    if (outarr == null || outarr.length < infblk.w * infblk.h) {
329:                        outarr = new int[infblk.w * infblk.h];
330:                        cblk.setData(outarr);
331:                    }
332:                    cblk.m = infblk.m;
333:                    cblk.n = infblk.n;
334:                    cblk.sb = infblk.sb;
335:                    cblk.ulx = infblk.ulx;
336:                    cblk.uly = infblk.uly;
337:                    cblk.w = infblk.w;
338:                    cblk.h = infblk.h;
339:                    cblk.wmseScaling = infblk.wmseScaling;
340:                    cblk.offset = 0;
341:                    cblk.scanw = cblk.w;
342:                }
343:
344:                // Cache width, height and subband of code-block
345:                w = cblk.w;
346:                h = cblk.h;
347:                sb = cblk.sb;
348:
349:                if (isReversible(tIdx, c)) { // Reversible only for int data
350:                    cblk.magbits = g - 1 + src.getNomRangeBits(c)
351:                            + sb.anGainExp;
352:                    shiftBits = 31 - cblk.magbits;
353:
354:                    // Update the convertFactor field
355:                    cblk.convertFactor = (1 << shiftBits);
356:
357:                    // Since we used getNextCodeBlock() to get the int data then
358:                    // 'offset' is 0 and 'scanw' is the width of the code-block The
359:                    // input and output arrays are the same (i.e. "in place")
360:                    for (j = w * h - 1; j >= 0; j--) {
361:                        tmp = (outarr[j] << shiftBits);
362:                        outarr[j] = ((tmp < 0) ? (1 << 31) | (-tmp) : tmp);
363:                    }
364:                } else { // Non-reversible, use step size
365:                    float baseStep = ((Float) qsss.getTileCompVal(tIdx, c))
366:                            .floatValue();
367:
368:                    // Calculate magnitude bits and quantization step size
369:                    if (isDerived(tIdx, c)) {
370:                        cblk.magbits = g - 1 + sb.level
371:                                - (int) Math.floor(Math.log(baseStep) / log2);
372:                        stepUDR = baseStep / (1 << sb.level);
373:                    } else {
374:                        cblk.magbits = g
375:                                - 1
376:                                - (int) Math.floor(Math.log(baseStep
377:                                        / (sb.l2Norm * (1 << sb.anGainExp)))
378:                                        / log2);
379:                        stepUDR = baseStep / (sb.l2Norm * (1 << sb.anGainExp));
380:                    }
381:                    shiftBits = 31 - cblk.magbits;
382:                    // Calculate step that decoder will get and use that one.
383:                    stepUDR = convertFromExpMantissa(convertToExpMantissa(stepUDR));
384:                    invstep = 1.0f / ((1L << (src.getNomRangeBits(c) + sb.anGainExp)) * stepUDR);
385:                    // Normalize to magnitude bits (output fractional point)
386:                    invstep *= (1 << (shiftBits - src.getFixedPoint(c)));
387:
388:                    // Update convertFactor and stepSize fields
389:                    cblk.convertFactor = invstep;
390:                    cblk.stepSize = ((1L << (src.getNomRangeBits(c) + sb.anGainExp)) * stepUDR);
391:
392:                    if (intq) { // Quantizing int data
393:                        // Since we used getNextCodeBlock() to get the int data then
394:                        // 'offset' is 0 and 'scanw' is the width of the code-block
395:                        // The input and output arrays are the same (i.e. "in place")
396:                        for (j = w * h - 1; j >= 0; j--) {
397:                            tmp = (int) (outarr[j] * invstep);
398:                            outarr[j] = ((tmp < 0) ? (1 << 31) | (-tmp) : tmp);
399:                        }
400:                    } else { // Quantizing float data
401:                        for (j = w * h - 1, k = infblk.offset + (h - 1)
402:                                * infblk.scanw + w - 1, jmin = w * (h - 1); j >= 0; jmin -= w) {
403:                            for (; j >= jmin; k--, j--) {
404:                                tmp = (int) (infarr[k] * invstep);
405:                                outarr[j] = ((tmp < 0) ? (1 << 31) | (-tmp)
406:                                        : tmp);
407:                            }
408:                            // Jump to beggining of previous line in input
409:                            k -= infblk.scanw - w;
410:                        }
411:                    }
412:                }
413:                // Return the quantized code-block
414:                return cblk;
415:            }
416:
417:            /**
418:             * Calculates the parameters of the SubbandAn objects that depend on the
419:             * Quantizer. The 'stepWMSE' field is calculated for each subband which is
420:             * a leaf in the tree rooted at 'sb', for the specified component. The
421:             * subband tree 'sb' must be the one for the component 'n'.
422:             *
423:             * @param sb The root of the subband tree.
424:             *
425:             * @param c The component index
426:             *
427:             * @see SubbandAn#stepWMSE
428:             * */
429:            protected void calcSbParams(SubbandAn sb, int c) {
430:                float baseStep;
431:
432:                if (sb.stepWMSE > 0f) // parameters already calculated
433:                    return;
434:                if (!sb.isNode) {
435:                    if (isReversible(tIdx, c)) {
436:                        sb.stepWMSE = (float) Math.pow(2, -(src
437:                                .getNomRangeBits(c) << 1))
438:                                * sb.l2Norm * sb.l2Norm;
439:                    } else {
440:                        baseStep = ((Float) qsss.getTileCompVal(tIdx, c))
441:                                .floatValue();
442:                        if (isDerived(tIdx, c)) {
443:                            sb.stepWMSE = baseStep
444:                                    * baseStep
445:                                    * (float) Math.pow(2,
446:                                            (sb.anGainExp - sb.level) << 1)
447:                                    * sb.l2Norm * sb.l2Norm;
448:                        } else {
449:                            sb.stepWMSE = baseStep * baseStep;
450:                        }
451:                    }
452:                } else {
453:                    calcSbParams((SubbandAn) sb.getLL(), c);
454:                    calcSbParams((SubbandAn) sb.getHL(), c);
455:                    calcSbParams((SubbandAn) sb.getLH(), c);
456:                    calcSbParams((SubbandAn) sb.getHH(), c);
457:                    sb.stepWMSE = 1f; // Signal that we already calculated this branch
458:                }
459:            }
460:
461:            /**
462:             * Converts the floating point value to its exponent-mantissa
463:             * representation. The mantissa occupies the 11 least significant bits
464:             * (bits 10-0), and the exponent the previous 5 bits (bits 15-11).
465:             *
466:             * @param step The quantization step, normalized to a dynamic range of 1.
467:             *
468:             * @return The exponent mantissa representation of the step.
469:             * */
470:            public static int convertToExpMantissa(float step) {
471:                int exp;
472:
473:                exp = (int) Math.ceil(-Math.log(step) / log2);
474:                if (exp > QSTEP_MAX_EXPONENT) {
475:                    // If step size is too small for exponent representation, use the
476:                    // minimum, which is exponent QSTEP_MAX_EXPONENT and mantissa 0.
477:                    return (QSTEP_MAX_EXPONENT << QSTEP_MANTISSA_BITS);
478:                }
479:                // NOTE: this formula does not support more than 5 bits for the
480:                // exponent, otherwise (-1<<exp) might overflow (the - is used to be
481:                // able to represent 2**31)
482:                return (exp << QSTEP_MANTISSA_BITS)
483:                        | ((int) ((-step * (-1 << exp) - 1f)
484:                                * (1 << QSTEP_MANTISSA_BITS) + 0.5f));
485:            }
486:
487:            /**
488:             * Converts the exponent-mantissa representation to its floating-point
489:             * value. The mantissa occupies the 11 least significant bits (bits 10-0),
490:             * and the exponent the previous 5 bits (bits 15-11).
491:             *
492:             * @param ems The exponent-mantissa representation of the step.
493:             *
494:             * @return The floating point representation of the step, normalized to a
495:             * dynamic range of 1.
496:             * */
497:            private static float convertFromExpMantissa(int ems) {
498:                // NOTE: this formula does not support more than 5 bits for the
499:                // exponent, otherwise (-1<<exp) might overflow (the - is used to be
500:                // able to represent 2**31)
501:                return (-1f - ((float) (ems & QSTEP_MAX_MANTISSA))
502:                        / ((float) (1 << QSTEP_MANTISSA_BITS)))
503:                        / (float) (-1 << ((ems >> QSTEP_MANTISSA_BITS) & QSTEP_MAX_EXPONENT));
504:            }
505:
506:            /**
507:             * Returns the maximum number of magnitude bits in any subband of the
508:             * current tile.
509:             *
510:             * @param c the component number
511:             *
512:             * @return The maximum number of magnitude bits in all subbands of the
513:             * current tile.
514:             * */
515:            public int getMaxMagBits(int c) {
516:                Subband sb = getAnSubbandTree(tIdx, c);
517:                if (isReversible(tIdx, c)) {
518:                    return getMaxMagBitsRev(sb, c);
519:                } else {
520:                    if (isDerived(tIdx, c)) {
521:                        return getMaxMagBitsDerived(sb, tIdx, c);
522:                    } else {
523:                        return getMaxMagBitsExpounded(sb, tIdx, c);
524:                    }
525:                }
526:            }
527:
528:            /**
529:             * Returns the maximum number of magnitude bits in any subband of the
530:             * current tile if reversible quantization is used
531:             *
532:             * @param sb The root of the subband tree of the current tile
533:             *
534:             * @param c the component number
535:             *
536:             * @return The highest number of magnitude bit-planes
537:             * */
538:            private int getMaxMagBitsRev(Subband sb, int c) {
539:                int tmp, max = 0;
540:                int g = ((Integer) gbs.getTileCompVal(tIdx, c)).intValue();
541:
542:                if (!sb.isNode)
543:                    return g - 1 + src.getNomRangeBits(c) + sb.anGainExp;
544:
545:                max = getMaxMagBitsRev(sb.getLL(), c);
546:                tmp = getMaxMagBitsRev(sb.getLH(), c);
547:                if (tmp > max)
548:                    max = tmp;
549:                tmp = getMaxMagBitsRev(sb.getHL(), c);
550:                if (tmp > max)
551:                    max = tmp;
552:                tmp = getMaxMagBitsRev(sb.getHH(), c);
553:                if (tmp > max)
554:                    max = tmp;
555:
556:                return max;
557:            }
558:
559:            /**
560:             * Returns the maximum number of magnitude bits in any subband in the
561:             * given tile-component if derived quantization is used
562:             *
563:             * @param sb The root of the subband tree of the tile-component
564:             *
565:             * @param t Tile index
566:             *
567:             * @param c Component index
568:             *
569:             * @return The highest number of magnitude bit-planes
570:             * */
571:            private int getMaxMagBitsDerived(Subband sb, int t, int c) {
572:                int tmp, max = 0;
573:                int g = ((Integer) gbs.getTileCompVal(t, c)).intValue();
574:
575:                if (!sb.isNode) {
576:                    float baseStep = ((Float) qsss.getTileCompVal(t, c))
577:                            .floatValue();
578:                    return g - 1 + sb.level
579:                            - (int) Math.floor(Math.log(baseStep) / log2);
580:                }
581:
582:                max = getMaxMagBitsDerived(sb.getLL(), t, c);
583:                tmp = getMaxMagBitsDerived(sb.getLH(), t, c);
584:                if (tmp > max)
585:                    max = tmp;
586:                tmp = getMaxMagBitsDerived(sb.getHL(), t, c);
587:                if (tmp > max)
588:                    max = tmp;
589:                tmp = getMaxMagBitsDerived(sb.getHH(), t, c);
590:                if (tmp > max)
591:                    max = tmp;
592:
593:                return max;
594:            }
595:
596:            /**
597:             * Returns the maximum number of magnitude bits in any subband in the
598:             * given tile-component if expounded quantization is used
599:             *
600:             * @param sb The root of the subband tree of the tile-component
601:             *
602:             * @param t Tile index
603:             *
604:             * @param c Component index
605:             *
606:             * @return The highest number of magnitude bit-planes
607:             * */
608:            private int getMaxMagBitsExpounded(Subband sb, int t, int c) {
609:                int tmp, max = 0;
610:                int g = ((Integer) gbs.getTileCompVal(t, c)).intValue();
611:
612:                if (!sb.isNode) {
613:                    float baseStep = ((Float) qsss.getTileCompVal(t, c))
614:                            .floatValue();
615:                    return g
616:                            - 1
617:                            - (int) Math
618:                                    .floor(Math
619:                                            .log(baseStep
620:                                                    / (((SubbandAn) sb).l2Norm * (1 << sb.anGainExp)))
621:                                            / log2);
622:                }
623:
624:                max = getMaxMagBitsExpounded(sb.getLL(), t, c);
625:                tmp = getMaxMagBitsExpounded(sb.getLH(), t, c);
626:                if (tmp > max)
627:                    max = tmp;
628:                tmp = getMaxMagBitsExpounded(sb.getHL(), t, c);
629:                if (tmp > max)
630:                    max = tmp;
631:                tmp = getMaxMagBitsExpounded(sb.getHH(), t, c);
632:                if (tmp > max)
633:                    max = tmp;
634:
635:                return max;
636:            }
637:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.