001/* 002 * $RCSfile: ForwCompTransf.java,v $ 003 * $Revision: 1.1 $ 004 * $Date: 2005/02/11 05:02:13 $ 005 * $State: Exp $ 006 * 007 * Class: ForwCompTransf 008 * 009 * Description: Component transformations applied to tiles 010 * 011 * 012 * 013 * COPYRIGHT: 014 * 015 * This software module was originally developed by Raphaël Grosbois and 016 * Diego Santa Cruz (Swiss Federal Institute of Technology-EPFL); Joel 017 * Askelöf (Ericsson Radio Systems AB); and Bertrand Berthelot, David 018 * Bouchard, Félix Henry, Gerard Mozelle and Patrice Onno (Canon Research 019 * Centre France S.A) in the course of development of the JPEG2000 020 * standard as specified by ISO/IEC 15444 (JPEG 2000 Standard). This 021 * software module is an implementation of a part of the JPEG 2000 022 * Standard. Swiss Federal Institute of Technology-EPFL, Ericsson Radio 023 * Systems AB and Canon Research Centre France S.A (collectively JJ2000 024 * Partners) agree not to assert against ISO/IEC and users of the JPEG 025 * 2000 Standard (Users) any of their rights under the copyright, not 026 * including other intellectual property rights, for this software module 027 * with respect to the usage by ISO/IEC and Users of this software module 028 * or modifications thereof for use in hardware or software products 029 * claiming conformance to the JPEG 2000 Standard. Those intending to use 030 * this software module in hardware or software products are advised that 031 * their use may infringe existing patents. The original developers of 032 * this software module, JJ2000 Partners and ISO/IEC assume no liability 033 * for use of this software module or modifications thereof. No license 034 * or right to this software module is granted for non JPEG 2000 Standard 035 * conforming products. JJ2000 Partners have full right to use this 036 * software module for his/her own purpose, assign or donate this 037 * software module to any third party and to inhibit third parties from 038 * using this software module for non JPEG 2000 Standard conforming 039 * products. This copyright notice must be included in all copies or 040 * derivative works of this software module. 041 * 042 * Copyright (c) 1999/2000 JJ2000 Partners. 043 * */ 044package jj2000.j2k.image.forwcomptransf; 045 046import jj2000.j2k.ModuleSpec; 047import jj2000.j2k.image.BlkImgDataSrc; 048import jj2000.j2k.image.CompTransfSpec; 049import jj2000.j2k.image.DataBlk; 050import jj2000.j2k.image.DataBlkFloat; 051import jj2000.j2k.image.DataBlkInt; 052import jj2000.j2k.image.ImgDataAdapter; 053import jj2000.j2k.util.MathUtil; 054import jj2000.j2k.wavelet.analysis.AnWTFilterSpec; 055 056import com.github.jaiimageio.jpeg2000.impl.J2KImageWriteParamJava; 057/** 058 * This class apply component transformations to the tiles depending 059 * on user specifications. These transformations can be used to 060 * improve compression efficiency but are not related to colour 061 * transforms used to map colour values for display purposes. JPEG 062 * 2000 part I defines 2 component transformations: RCT (Reversible 063 * Component Transformation) and ICT (Irreversible Component 064 * Transformation). 065 * 066 * @see ModuleSpec 067 * */ 068public class ForwCompTransf extends ImgDataAdapter 069 implements BlkImgDataSrc { 070 071 /** Identifier for no component transformation. Value is 0. */ 072 public static final int NONE = 0; 073 074 /** Identifier for the Forward Reversible Component Transformation 075 (FORW_RCT). Value is 1. */ 076 public static final int FORW_RCT = 1; 077 078 /** Identifier for the Forward Irreversible Component 079 Transformation (FORW_ICT). Value is 2 */ 080 public static final int FORW_ICT = 2; 081 082 /** The source of image data */ 083 private BlkImgDataSrc src; 084 085 /** The component transformations specifications */ 086 private CompTransfSpec cts; 087 088 /** The wavelet filter specifications */ 089 private AnWTFilterSpec wfs; 090 091 /** The type of the current component transformation JPEG 2000 092 * part I only support NONE, FORW_RCT and FORW_ICT types*/ 093 private int transfType = NONE; 094 095 /** The bit-depths of transformed components */ 096 private int tdepth[]; 097 098 /** Output block used instead of the one provided as an argument 099 if the later is DataBlkFloat.*/ 100 private DataBlk outBlk; 101 102 /** Block used to request component with index 0 */ 103 private DataBlkInt block0; 104 105 /** Block used to request component with index 1*/ 106 private DataBlkInt block1; 107 108 /** Block used to request component with index 2*/ 109 private DataBlkInt block2; 110 111 /** 112 * Constructs a new ForwCompTransf object that operates on the 113 * specified source of image data. 114 * 115 * @param imgSrc The source from where to get the data to be 116 * transformed 117 * 118 * @param encSpec The encoder specifications 119 * 120 * @see BlkImgDataSrc 121 * */ 122 public ForwCompTransf(BlkImgDataSrc imgSrc, J2KImageWriteParamJava wp) { 123 super(imgSrc); 124 this.cts = wp.getComponentTransformation(); 125 this.wfs = wp.getFilters(); 126 src = imgSrc; 127 } 128 129 /** The prefix for component transformation type: 'M' */ 130 public final static char OPT_PREFIX = 'M'; 131 132 /** The list of parameters that is accepted by the forward 133 * component transformation module. Options start with an 'M'. */ 134 private final static String [][] pinfo = { 135 { "Mct", "[<tile index>] [true|false] ...", 136 "Specifies to use component transformation with some tiles. "+ 137 " If the wavelet transform is reversible (w5x3 filter), the "+ 138 "Reversible Component Transformation (RCT) is applied. If not "+ 139 "(w9x7 filter), the Irreversible Component Transformation (ICT)"+ 140 " is used.", null}, 141 }; 142 143 /** 144 * Returns the position of the fixed point in the specified 145 * component. This is the position of the least significant integral 146 * (i.e. non-fractional) bit, which is equivalent to the number of 147 * fractional bits. For instance, for fixed-point values with 2 fractional 148 * bits, 2 is returned. For floating-point data this value does not apply 149 * and 0 should be returned. Position 0 is the position of the least 150 * significant bit in the data. 151 * 152 * <P>This default implementation assumes that the number of 153 * fractional bits is not modified by the component mixer. 154 * 155 * @param c The index of the component. 156 * 157 * @return The value of the fixed point position of the source 158 * since the color transform does not affect it. 159 * */ 160 public int getFixedPoint(int c){ 161 return src.getFixedPoint(c); 162 } 163 164 /** 165 * Returns the parameters that are used in this class and implementing 166 * classes. It returns a 2D String array. Each of the 1D arrays is for a 167 * different option, and they have 4 elements. The first element is the 168 * option name, the second one is the synopsis, the third one is a long 169 * description of what the parameter is and the fourth is its default 170 * value. The synopsis or description may be 'null', in which case it is 171 * assumed that there is no synopsis or description of the option, 172 * respectively. Null may be returned if no options are supported. 173 * 174 * @return the options name, their synopsis and their explanation, 175 * or null if no options are supported. 176 * */ 177 public static String[][] getParameterInfo(){ 178 return pinfo; 179 } 180 181 /** 182 * Calculates the bitdepths of the transformed components, given the 183 * bitdepth of the un-transformed components and the component 184 * tranformation type. 185 * 186 * @param ntdepth The bitdepth of each non-transformed components. 187 * 188 * @param ttype The type ID of the component transformation. 189 * 190 * @param tdepth If not null the results are stored in this 191 * array, otherwise a new array is allocated and returned. 192 * 193 * @return The bitdepth of each transformed component. 194 * */ 195 public static 196 int[] calcMixedBitDepths(int ntdepth[], int ttype, int tdepth[]) { 197 198 if (ntdepth.length < 3 && ttype != NONE) { 199 throw new IllegalArgumentException(); 200 } 201 202 if (tdepth == null) { 203 tdepth = new int[ntdepth.length]; 204 } 205 206 switch (ttype) { 207 case NONE: 208 System.arraycopy(ntdepth,0,tdepth,0,ntdepth.length); 209 break; 210 case FORW_RCT: 211 if (ntdepth.length >3) { 212 System.arraycopy(ntdepth,3,tdepth,3,ntdepth.length-3); 213 } 214 // The formulas are: 215 // tdepth[0] = ceil(log2(2^(ntdepth[0])+2^ntdepth[1]+ 216 // 2^(ntdepth[2])))-2+1 217 // tdepth[1] = ceil(log2(2^(ntdepth[1])+2^(ntdepth[2])-1))+1 218 // tdepth[2] = ceil(log2(2^(ntdepth[0])+2^(ntdepth[1])-1))+1 219 // The MathUtil.log2(x) function calculates floor(log2(x)), so we 220 // use 'MathUtil.log2(2*x-1)+1', which calculates ceil(log2(x)) 221 // for any x>=1, x integer. 222 tdepth[0] = MathUtil.log2((1<<ntdepth[0])+(2<<ntdepth[1])+ 223 (1<<ntdepth[2])-1)-2+1; 224 tdepth[1] = MathUtil.log2((1<<ntdepth[2])+(1<<ntdepth[1])-1)+1; 225 tdepth[2] = MathUtil.log2((1<<ntdepth[0])+(1<<ntdepth[1])-1)+1; 226 break; 227 case FORW_ICT: 228 if (ntdepth.length >3) { 229 System.arraycopy(ntdepth,3,tdepth,3,ntdepth.length-3); 230 } 231 // The MathUtil.log2(x) function calculates floor(log2(x)), so we 232 // use 'MathUtil.log2(2*x-1)+1', which calculates ceil(log2(x)) 233 // for any x>=1, x integer. 234 tdepth[0] = 235 MathUtil.log2((int)Math.floor((1<<ntdepth[0])*0.299072+ 236 (1<<ntdepth[1])*0.586914+ 237 (1<<ntdepth[2])*0.114014)-1)+1; 238 tdepth[1] = 239 MathUtil.log2((int)Math.floor((1<<ntdepth[0])*0.168701+ 240 (1<<ntdepth[1])*0.331299+ 241 (1<<ntdepth[2])*0.5)-1)+1; 242 tdepth[2] = 243 MathUtil.log2((int)Math.floor((1<<ntdepth[0])*0.5+ 244 (1<<ntdepth[1])*0.418701+ 245 (1<<ntdepth[2])*0.081299)-1)+1; 246 break; 247 } 248 249 return tdepth; 250 } 251 252 /** 253 * Initialize some variables used with RCT. It must be called, at least, 254 * at the beginning of each new tile. 255 * */ 256 private void initForwRCT(){ 257 int i; 258 int tIdx = getTileIdx(); 259 260 if (src.getNumComps() < 3) { 261 throw new IllegalArgumentException(); 262 } 263 // Check that the 3 components have the same dimensions 264 if (src.getTileCompWidth(tIdx, 0) != src.getTileCompWidth(tIdx, 1) || 265 src.getTileCompWidth(tIdx, 0) != src.getTileCompWidth(tIdx, 2) || 266 src.getTileCompHeight(tIdx, 0) != src.getTileCompHeight(tIdx, 1) || 267 src.getTileCompHeight(tIdx, 0) != src.getTileCompHeight(tIdx, 2)) { 268 throw new IllegalArgumentException("Can not use RCT "+ 269 "on components with different "+ 270 "dimensions"); 271 } 272 // Initialize bitdepths 273 int utd[]; // Premix bitdepths 274 utd = new int[src.getNumComps()]; 275 for (i=utd.length-1; i>=0; i--) { 276 utd[i] = src.getNomRangeBits(i); 277 } 278 tdepth = calcMixedBitDepths(utd,FORW_RCT,null); 279 } 280 281 /** 282 * Initialize some variables used with ICT. It must be called, at least, 283 * at the beginning of a new tile. 284 * */ 285 private void initForwICT(){ 286 int i; 287 int tIdx = getTileIdx(); 288 289 if (src.getNumComps() < 3) { 290 throw new IllegalArgumentException(); 291 } 292 // Check that the 3 components have the same dimensions 293 if (src.getTileCompWidth(tIdx, 0) != src.getTileCompWidth(tIdx, 1) || 294 src.getTileCompWidth(tIdx, 0) != src.getTileCompWidth(tIdx, 2) || 295 src.getTileCompHeight(tIdx, 0) != src.getTileCompHeight(tIdx, 1) || 296 src.getTileCompHeight(tIdx, 0) != src.getTileCompHeight(tIdx, 2)) { 297 throw new IllegalArgumentException("Can not use ICT "+ 298 "on components with different "+ 299 "dimensions"); 300 } 301 // Initialize bitdepths 302 int utd[]; // Premix bitdepths 303 utd = new int[src.getNumComps()]; 304 for (i=utd.length-1; i>=0; i--) { 305 utd[i] = src.getNomRangeBits(i); 306 } 307 tdepth = calcMixedBitDepths(utd,FORW_ICT,null); 308 } 309 310 /** 311 * Returns a string with a descriptive text of which forward component 312 * transformation is used. This can be either "Forward RCT" or "Forward 313 * ICT" or "No component transformation" depending on the current tile. 314 * 315 * @return A descriptive string 316 * */ 317 public String toString() { 318 switch(transfType){ 319 case FORW_RCT: 320 return "Forward RCT"; 321 case FORW_ICT: 322 return "Forward ICT"; 323 case NONE: 324 return "No component transformation"; 325 default: 326 throw new IllegalArgumentException("Non JPEG 2000 part I"+ 327 " component transformation"); 328 } 329 } 330 331 /** 332 * Returns the number of bits, referred to as the "range bits", 333 * corresponding to the nominal range of the data in the specified 334 * component and in the current tile. If this number is <i>b</i> then for 335 * unsigned data the nominal range is between 0 and 2^b-1, and for signed 336 * data it is between -2^(b-1) and 2^(b-1)-1. Note that this value can be 337 * affected by the multiple component transform. 338 * 339 * @param c The index of the component. 340 * 341 * @return The bitdepth of component 'c' after mixing. 342 * */ 343 public int getNomRangeBits(int c) { 344 switch(transfType){ 345 case FORW_RCT: 346 case FORW_ICT: 347 return tdepth[c]; 348 case NONE: 349 return src.getNomRangeBits(c); 350 default: 351 throw new IllegalArgumentException("Non JPEG 2000 part I"+ 352 " component transformation"); 353 } 354 } 355 356 /** 357 * Returns true if this transform is reversible in current 358 * tile. Reversible component transformations are those which operation 359 * can be completely reversed without any loss of information (not even 360 * due to rounding). 361 * 362 * @return Reversibility of component transformation in current tile 363 * */ 364 public boolean isReversible(){ 365 switch(transfType){ 366 case NONE: 367 case FORW_RCT: 368 return true; 369 case FORW_ICT: 370 return false; 371 default: 372 throw new IllegalArgumentException("Non JPEG 2000 part I"+ 373 " component transformation"); 374 } 375 } 376 377 /** 378 * Apply forward component transformation associated with the current 379 * tile. If no component transformation has been requested by the user, 380 * data are not modified. 381 * 382 * <P>This method calls the getInternCompData() method, but respects the 383 * definitions of the getCompData() method defined in the BlkImgDataSrc 384 * interface. 385 * 386 * @param blk Determines the rectangular area to return, and the 387 * data is returned in this object. 388 * 389 * @param c Index of the output component. 390 * 391 * @return The requested DataBlk 392 * 393 * @see BlkImgDataSrc#getCompData 394 * */ 395 public DataBlk getCompData(DataBlk blk, int c){ 396 // If requesting a component whose index is greater than 3 or there is 397 // no transform return a copy of data (getInternCompData returns the 398 // actual data in those cases) 399 if (c>=3 || transfType == NONE) { 400 return src.getCompData(blk,c); 401 } 402 else { // We can use getInternCompData (since data is a copy anyways) 403 return getInternCompData(blk,c); 404 } 405 } 406 407 /** 408 * Apply the component transformation associated with the current tile. If 409 * no component transformation has been requested by the user, data are 410 * not modified. Else, appropriate method is called (forwRCT or forwICT). 411 * 412 * @see #forwRCT 413 * 414 * @see #forwICT 415 * 416 * @param blk Determines the rectangular area to return. 417 * 418 * @param c Index of the output component. 419 * 420 * @return The requested DataBlk 421 * */ 422 public DataBlk getInternCompData(DataBlk blk, int c){ 423 switch(transfType){ 424 case NONE: 425 return src.getInternCompData(blk,c); 426 case FORW_RCT: 427 return forwRCT(blk,c); 428 case FORW_ICT: 429 return forwICT(blk,c); 430 default: 431 throw new IllegalArgumentException("Non JPEG 2000 part I component"+ 432 " transformation for tile: "+ 433 tIdx); 434 } 435 } 436 437 /** 438 * Apply forward component transformation to obtain requested component 439 * from specified block of data. Whatever the type of requested DataBlk, 440 * it always returns a DataBlkInt. 441 * 442 * @param blk Determine the rectangular area to return 443 * 444 * @param c The index of the requested component 445 * 446 * @return Data of requested component 447 * */ 448 private DataBlk forwRCT(DataBlk blk,int c){ 449 int k,k0,k1,k2,mink,i; 450 int w = blk.w; //width of output block 451 int h = blk.h; //height of ouput block 452 int outdata[]; //array of output data 453 454 //If asking for Yr, Ur or Vr do transform 455 if(c >= 0 && c <= 2) { 456 // Check that request data type is int 457 if(blk.getDataType()!=DataBlk.TYPE_INT){ 458 if(outBlk==null || outBlk.getDataType() != DataBlk.TYPE_INT){ 459 outBlk = new DataBlkInt(); 460 } 461 outBlk.w = w; 462 outBlk.h = h; 463 outBlk.ulx = blk.ulx; 464 outBlk.uly = blk.uly; 465 blk = outBlk; 466 } 467 468 //Reference to output block data array 469 outdata = (int[]) blk.getData(); 470 471 //Create data array of blk if necessary 472 if(outdata == null || outdata.length<h*w) { 473 outdata = new int[h*w]; 474 blk.setData(outdata); 475 } 476 477 // Block buffers for input RGB data 478 int data0[],data1[],bdata[]; // input data arrays 479 480 if(block0==null) 481 block0 = new DataBlkInt(); 482 if(block1==null) 483 block1 = new DataBlkInt(); 484 if(block2==null) 485 block2 = new DataBlkInt(); 486 block0.w = block1.w = block2.w = blk.w; 487 block0.h = block1.h = block2.h = blk.h; 488 block0.ulx = block1.ulx = block2.ulx = blk.ulx; 489 block0.uly = block1.uly = block2.uly = blk.uly; 490 491 //Fill in buffer blocks (to be read only) 492 // Returned blocks may have different size and position 493 block0 = (DataBlkInt)src.getInternCompData(block0, 0); 494 data0 = (int[]) block0.getData(); 495 block1 = (DataBlkInt)src.getInternCompData(block1, 1); 496 data1 = (int[]) block1.getData(); 497 block2 = (DataBlkInt)src.getInternCompData(block2, 2); 498 bdata = (int[]) block2.getData(); 499 500 // Set the progressiveness of the output data 501 blk.progressive = block0.progressive || block1.progressive || 502 block2.progressive; 503 blk.offset = 0; 504 blk.scanw = w; 505 506 //Perform conversion 507 508 // Initialize general indexes 509 k = w*h-1; 510 k0 = block0.offset+(h-1)*block0.scanw+w-1; 511 k1 = block1.offset+(h-1)*block1.scanw+w-1; 512 k2 = block2.offset+(h-1)*block2.scanw+w-1; 513 514 switch(c) { 515 case 0: //RGB to Yr conversion 516 for (i = h-1; i >= 0; i--) { 517 for (mink = k-w; k > mink; k--, k0--, k1--, k2--) { 518 // Use int arithmetic with 12 fractional bits 519 // and rounding 520 outdata[k] = 521 ( data0[k] + 2 * data1[k] + bdata[k] 522 ) >> 2; // Same as / 4 523 } 524 // Jump to beggining of previous line in input 525 k0 -= block0.scanw - w; 526 k1 -= block1.scanw - w; 527 k2 -= block2.scanw - w; 528 } 529 break; 530 531 case 1: //RGB to Ur conversion 532 for (i = h-1; i >= 0; i--) { 533 for (mink = k-w; k > mink; k--, k1--, k2--) { 534 // Use int arithmetic with 12 fractional bits 535 // and rounding 536 outdata[k] = bdata[k2] - data1[k1]; 537 } 538 // Jump to beggining of previous line in input 539 k1 -= block1.scanw - w; 540 k2 -= block2.scanw - w; 541 } 542 break; 543 544 case 2: //RGB to Vr conversion 545 for (i = h-1; i >= 0; i--) { 546 for (mink = k-w; k > mink; k--, k0--, k1--) { 547 // Use int arithmetic with 12 fractional bits 548 // and rounding 549 outdata[k] = data0[k0] - data1[k1]; 550 } 551 // Jump to beggining of previous line in input 552 k0 -= block0.scanw - w; 553 k1 -= block1.scanw - w; 554 } 555 break; 556 557 } 558 } 559 else if (c >= 3) { 560 // Requesting a component which is not Y, Ur or Vr => 561 // just pass the data 562 return src.getInternCompData(blk,c); 563 } 564 else { 565 // Requesting a non valid component index 566 throw new IllegalArgumentException(); 567 } 568 return blk; 569 570 } 571 572 /** 573 * Apply forward irreversible component transformation to obtain requested 574 * component from specified block of data. Whatever the type of requested 575 * DataBlk, it always returns a DataBlkFloat. 576 * 577 * @param blk Determine the rectangular area to return 578 * 579 * @param c The index of the requested component 580 * 581 * @return Data of requested component 582 * */ 583 private DataBlk forwICT(DataBlk blk,int c){ 584 int k,k0,k1,k2,mink,i; 585 int w = blk.w; //width of output block 586 int h = blk.h; //height of ouput block 587 float outdata[]; //array of output data 588 589 if(blk.getDataType()!=DataBlk.TYPE_FLOAT){ 590 if(outBlk==null || outBlk.getDataType() != DataBlk.TYPE_FLOAT){ 591 outBlk = new DataBlkFloat(); 592 } 593 outBlk.w = w; 594 outBlk.h = h; 595 outBlk.ulx = blk.ulx; 596 outBlk.uly = blk.uly; 597 blk = outBlk; 598 } 599 600 //Reference to output block data array 601 outdata = (float[]) blk.getData(); 602 603 //Create data array of blk if necessary 604 if(outdata == null || outdata.length<w*h) { 605 outdata = new float[h * w]; 606 blk.setData(outdata); 607 } 608 609 //If asking for Y, Cb or Cr do transform 610 if(c>=0 && c<=2) { 611 612 int data0[],data1[],data2[]; // input data arrays 613 614 if(block0==null) 615 block0 = new DataBlkInt(); 616 if(block1==null) 617 block1 = new DataBlkInt(); 618 if(block2==null) 619 block2 = new DataBlkInt(); 620 block0.w = block1.w = block2.w = blk.w; 621 block0.h = block1.h = block2.h = blk.h; 622 block0.ulx = block1.ulx = block2.ulx = blk.ulx; 623 block0.uly = block1.uly = block2.uly = blk.uly; 624 625 // Returned blocks may have different size and position 626 block0 = (DataBlkInt)src.getInternCompData(block0, 0); 627 data0 = (int[]) block0.getData(); 628 block1 = (DataBlkInt)src.getInternCompData(block1, 1); 629 data1 = (int[]) block1.getData(); 630 block2 = (DataBlkInt)src.getInternCompData(block2, 2); 631 data2 = (int[]) block2.getData(); 632 633 // Set the progressiveness of the output data 634 blk.progressive = block0.progressive || block1.progressive || 635 block2.progressive; 636 blk.offset = 0; 637 blk.scanw = w; 638 639 //Perform conversion 640 641 // Initialize general indexes 642 k = w*h-1; 643 k0 = block0.offset+(h-1)*block0.scanw+w-1; 644 k1 = block1.offset+(h-1)*block1.scanw+w-1; 645 k2 = block2.offset+(h-1)*block2.scanw+w-1; 646 647 switch(c) { 648 case 0: 649 //RGB to Y conversion 650 for (i = h-1; i >= 0; i--) { 651 for (mink = k-w; k > mink; k--, k0--, k1--, k2--) { 652 outdata[k] = 653 0.299f * data0[k0] 654 + 0.587f * data1[k1] 655 + 0.114f * data2[k2]; 656 } 657 // Jump to beggining of previous line in input 658 k0 -= block0.scanw - w; 659 k1 -= block1.scanw - w; 660 k2 -= block2.scanw - w; 661 } 662 break; 663 664 case 1: 665 //RGB to Cb conversion 666 for (i = h-1; i >= 0; i--) { 667 for (mink = k-w; k > mink; k--, k0--, k1--, k2--) { 668 outdata[k] = 669 - 0.16875f * data0[k0] 670 - 0.33126f * data1[k1] 671 + 0.5f * data2[k2]; 672 } 673 // Jump to beggining of previous line in input 674 k0 -= block0.scanw - w; 675 k1 -= block1.scanw - w; 676 k2 -= block2.scanw - w; 677 } 678 break; 679 680 case 2: 681 //RGB to Cr conversion 682 for (i = h-1; i >= 0; i--) { 683 for (mink = k-w; k > mink; k--, k0--, k1--, k2--) { 684 outdata[k] = 685 0.5f * data0[k0] 686 - 0.41869f * data1[k1] 687 - 0.08131f * data2[k2]; 688 } 689 // Jump to beggining of previous line in input 690 k0 -= block0.scanw - w; 691 k1 -= block1.scanw - w; 692 k2 -= block2.scanw - w; 693 } 694 break; 695 } 696 } 697 else if(c>=3) { 698 // Requesting a component which is not Y, Cb or Cr => 699 // just pass the data 700 701 // Variables 702 DataBlkInt indb = new DataBlkInt(blk.ulx,blk.uly,w,h); 703 int indata[]; // input data array 704 705 // Get the input data 706 // (returned block may be larger than requested one) 707 src.getInternCompData(indb,c); 708 indata = (int[]) indb.getData(); 709 710 // Copy the data converting from int to float 711 k = w*h-1; 712 k0 = indb.offset+(h-1)*indb.scanw+w-1; 713 for (i=h-1; i>=0; i--) { 714 for (mink = k-w; k > mink; k--, k0--) { 715 outdata[k] = (float) indata[k0]; 716 } 717 // Jump to beggining of next line in input 718 k0 += indb.w - w; 719 } 720 721 // Set the progressivity 722 blk.progressive = indb.progressive; 723 blk.offset = 0; 724 blk.scanw = w; 725 return blk; 726 } 727 else { 728 // Requesting a non valid component index 729 throw new IllegalArgumentException(); 730 } 731 return blk; 732 733 } 734 735 /** 736 * Changes the current tile, given the new indexes. An 737 * IllegalArgumentException is thrown if the indexes do not correspond to 738 * a valid tile. 739 * 740 * <P>This default implementation changes the tile in the source and 741 * re-initializes properly component transformation variables.. 742 * 743 * @param x The horizontal index of the tile. 744 * 745 * @param y The vertical index of the new tile. 746 * */ 747 public void setTile(int x, int y) { 748 src.setTile(x,y); 749 tIdx = getTileIdx(); // index of the current tile 750 751 // initializations 752 String str = (String)cts.getTileDef(tIdx); 753 if(str.equals("none")){ 754 transfType = NONE; 755 } 756 else if(str.equals("rct")){ 757 transfType = FORW_RCT; 758 initForwRCT(); 759 } 760 else if(str.equals("ict")){ 761 transfType = FORW_ICT; 762 initForwICT(); 763 } 764 else{ 765 throw new IllegalArgumentException("Component transformation"+ 766 " not recognized"); 767 } 768 } 769 770 /** 771 * Advances to the next tile, in standard scan-line order (by rows then 772 * columns). An NoNextElementException is thrown if the current tile is 773 * the last one (i.e. there is no next tile). 774 * 775 * <P>This default implementation just advances to the next tile in the 776 * source and re-initializes properly component transformation variables. 777 * */ 778 public void nextTile() { 779 src.nextTile(); 780 tIdx = getTileIdx(); // index of the current tile 781 782 // initializations 783 String str = (String)cts.getTileDef(tIdx); 784 if(str.equals("none")){ 785 transfType = NONE; 786 } 787 else if(str.equals("rct")){ 788 transfType = FORW_RCT; 789 initForwRCT(); 790 } 791 else if(str.equals("ict")){ 792 transfType = FORW_ICT; 793 initForwICT(); 794 } 795 else{ 796 throw new IllegalArgumentException("Component transformation"+ 797 " not recognized"); 798 } 799 } 800 801}