/// <summary> Returns, in the blk argument, the block of image data containing the /// specifed rectangular area, in the specified component. The data is /// returned, as a reference to the internal data, if any, instead of as a /// copy, therefore the returned data should not be modified. /// /// <P> After being read the coefficients are level shifted by subtracting /// 2^(nominal bit range - 1) /// /// <P>The rectangular area to return is specified by the 'ulx', 'uly', 'w' /// and 'h' members of the 'blk' argument, relative to the current /// tile. These members are not modified by this method. The 'offset' and /// 'scanw' of the returned data can be arbitrary. See the 'DataBlk' class. /// /// <P>If the data array in <tt>blk</tt> is <tt>null</tt>, then a new one /// is created if necessary. The implementation of this interface may /// choose to return the same array or a new one, depending on what is more /// efficient. Therefore, the data array in <tt>blk</tt> prior to the /// method call should not be considered to contain the returned data, a /// new array may have been created. Instead, get the array from /// <tt>blk</tt> after the method has returned. /// /// <P>The returned data always has its 'progressive' attribute unset /// (i.e. false). /// /// <P>When an I/O exception is encountered the JJ2KExceptionHandler is /// used. The exception is passed to its handleException method. The action /// that is taken depends on the action that has been registered in /// JJ2KExceptionHandler. See JJ2KExceptionHandler for details. /// /// <P>This method implements buffering for the 3 components: When the /// first one is asked, all the 3 components are read and stored until they /// are needed. /// /// </summary> /// <param name="blk">Its coordinates and dimensions specify the area to /// return. Some fields in this object are modified to return the data. /// /// </param> /// <param name="c">The index of the component from which to get the data. Only 0, /// 1 and 3 are valid. /// /// </param> /// <returns> The requested DataBlk /// /// </returns> /// <seealso cref="getCompData"> /// /// </seealso> /// <seealso cref="JJ2KExceptionHandler"> /// /// </seealso> public override DataBlk getInternCompData(DataBlk blk, int c) { // Check component index if (c < 0 || c > 2) { throw new System.ArgumentException(); } // Check type of block provided as an argument if (blk.DataType != DataBlk.TYPE_INT) { if (intBlk == null) { intBlk = new DataBlkInt(blk.ulx, blk.uly, blk.w, blk.h); } else { intBlk.ulx = blk.ulx; intBlk.uly = blk.uly; intBlk.w = blk.w; intBlk.h = blk.h; } blk = intBlk; } // If asking a component for the first time for this block, read the 3 // components if ((barr[c] == null) || (dbi.ulx > blk.ulx) || (dbi.uly > blk.uly) || (dbi.ulx + dbi.w < blk.ulx + blk.w) || (dbi.uly + dbi.h < blk.uly + blk.h)) { int k, j, i, mi; int[] red, green, blue; // Reset data arrays if needed if (barr[c] == null || barr[c].Length < blk.w * blk.h) { barr[c] = new int[blk.w * blk.h]; } blk.Data = barr[c]; i = (c + 1) % 3; if (barr[i] == null || barr[i].Length < blk.w * blk.h) { barr[i] = new int[blk.w * blk.h]; } i = (c + 2) % 3; if (barr[i] == null || barr[i].Length < blk.w * blk.h) { barr[i] = new int[blk.w * blk.h]; } // set attributes of the DataBlk used for buffering dbi.ulx = blk.ulx; dbi.uly = blk.uly; dbi.w = blk.w; dbi.h = blk.h; // Check line buffer if (buf == null || buf.Length < 3 * blk.w) { buf = new byte[3 * blk.w]; } red = barr[0]; green = barr[1]; blue = barr[2]; try { // Read line by line mi = blk.uly + blk.h; for (i = blk.uly; i < mi; i++) { // Reposition in input offset takes care of // header offset in_Renamed.Seek(offset + i * 3 * w + 3 * blk.ulx, System.IO.SeekOrigin.Begin); in_Renamed.Read(buf, 0, 3 * blk.w); for (k = (i - blk.uly) * blk.w + blk.w - 1, j = 3 * blk.w - 1; j >= 0; k--) { // Read every third sample blue[k] = (((byte)buf[j--]) & 0xFF) - DC_OFFSET; green[k] = (((byte)buf[j--]) & 0xFF) - DC_OFFSET; red[k] = (((byte)buf[j--]) & 0xFF) - DC_OFFSET; } } } catch (System.IO.IOException e) { JJ2KExceptionHandler.handleException(e); } barr[0] = red; barr[1] = green; barr[2] = blue; // Set buffer attributes blk.Data = barr[c]; blk.offset = 0; blk.scanw = blk.w; } else { //Asking for the 2nd or 3rd block component blk.Data = barr[c]; blk.offset = (blk.ulx - dbi.ulx) * dbi.w + blk.ulx - dbi.ulx; blk.scanw = dbi.scanw; } // Turn off the progressive attribute blk.progressive = false; return(blk); }
/// <summary> Returns, in the blk argument, the block of image data containing the /// specifed rectangular area, in the specified component. The data is /// returned, as a reference to the internal data, if any, instead of as a /// copy, therefore the returned data should not be modified. /// /// <p>After being read the coefficients are level shifted by subtracting /// 2^(nominal bit range - 1)<p> /// /// <p>The rectangular area to return is specified by the 'ulx', 'uly', 'w' /// and 'h' members of the 'blk' argument, relative to the current /// tile. These members are not modified by this method. The 'offset' and /// 'scanw' of the returned data can be arbitrary. See the 'DataBlk' /// class.</p> /// /// <p>If the data array in <tt>blk</tt> is <tt>null</tt>, then a new one /// is created if necessary. The implementation of this interface may /// choose to return the same array or a new one, depending on what is more /// efficient. Therefore, the data array in <tt>blk</tt> prior to the /// method call should not be considered to contain the returned data, a /// new array may have been created. Instead, get the array from /// <tt>blk</tt> after the method has returned.</p> /// /// <p>The returned data always has its 'progressive' attribute unset /// (i.e. false).</p> /// /// <p>When an I/O exception is encountered the JJ2KExceptionHandler is /// used. The exception is passed to its handleException method. The action /// that is taken depends on the action that has been registered in /// JJ2KExceptionHandler. See JJ2KExceptionHandler for details.</p> /// /// </summary> /// <param name="blk">Its coordinates and dimensions specify the area to /// return. Some fields in this object are modified to return the data. /// /// </param> /// <param name="c">The index of the component from which to get the data. Only 0 /// is valid. /// /// </param> /// <returns> The requested DataBlk /// /// </returns> /// <seealso cref="getCompData"> /// </seealso> /// <seealso cref="JJ2KExceptionHandler"> /// /// </seealso> public override DataBlk getInternCompData(DataBlk blk, int c) { int k, j, i, mi; // counters int levShift = 1 << (bitDepth - 1); // Check component index if (c != 0) { throw new System.ArgumentException(); } // Check type of block provided as an argument if (blk.DataType != DataBlk.TYPE_INT) { if (intBlk == null) { intBlk = new DataBlkInt(blk.ulx, blk.uly, blk.w, blk.h); } else { intBlk.ulx = blk.ulx; intBlk.uly = blk.uly; intBlk.w = blk.w; intBlk.h = blk.h; } blk = intBlk; } // Get data array int[] barr = (int[])blk.Data; if (barr == null || barr.Length < blk.w * blk.h * packBytes) { barr = new int[blk.w * blk.h]; blk.Data = barr; } int paddingLength = (32 - bitDepth); if (buf == null || buf.Length < packBytes * blk.w) { buf = new byte[packBytes * blk.w]; } try { switch (packBytes) { // Switch between one of the 3 byte packet type case 1: // Samples packed into 1 byte // Read line by line mi = blk.uly + blk.h; if (isSigned) { for (i = blk.uly; i < mi; i++) { // Reposition in input in_Renamed.Seek(offset + i * w + blk.ulx, System.IO.SeekOrigin.Begin); in_Renamed.Read(buf, 0, blk.w); for (k = (i - blk.uly) * blk.w + blk.w - 1, j = blk.w - 1; j >= 0; k--) { barr[k] = (((buf[j--] & 0xFF) << paddingLength) >> paddingLength); } } } else { // Not signed for (i = blk.uly; i < mi; i++) { // Reposition in input in_Renamed.Seek(offset + i * w + blk.ulx, System.IO.SeekOrigin.Begin); in_Renamed.Read(buf, 0, blk.w); for (k = (i - blk.uly) * blk.w + blk.w - 1, j = blk.w - 1; j >= 0; k--) { barr[k] = (SupportClass.URShift(((buf[j--] & 0xFF) << paddingLength), paddingLength)) - levShift; } } } break; case 2: // Samples packed into 2 bytes // Read line by line mi = blk.uly + blk.h; if (isSigned) { for (i = blk.uly; i < mi; i++) { // Reposition in input in_Renamed.Seek(offset + 2 * (i * w + blk.ulx), System.IO.SeekOrigin.Begin); in_Renamed.Read(buf, 0, blk.w << 1); switch (byteOrder) { case CSJ2K.j2k.io.EndianType_Fields.LITTLE_ENDIAN: for (k = (i - blk.uly) * blk.w + blk.w - 1, j = (blk.w << 1) - 1; j >= 0; k--) { barr[k] = ((((buf[j--] & 0xFF) << 8) | (buf[j--] & 0xFF)) << paddingLength) >> paddingLength; } break; case CSJ2K.j2k.io.EndianType_Fields.BIG_ENDIAN: for (k = (i - blk.uly) * blk.w + blk.w - 1, j = (blk.w << 1) - 1; j >= 0; k--) { barr[k] = (((buf[j--] & 0xFF) | ((buf[j--] & 0xFF) << 8)) << paddingLength) >> paddingLength; } break; default: throw new System.ApplicationException("Internal JJ2000 bug"); } } } else { // If not signed for (i = blk.uly; i < mi; i++) { // Reposition in input in_Renamed.Seek(offset + 2 * (i * w + blk.ulx), System.IO.SeekOrigin.Begin); in_Renamed.Read(buf, 0, blk.w << 1); switch (byteOrder) { case CSJ2K.j2k.io.EndianType_Fields.LITTLE_ENDIAN: for (k = (i - blk.uly) * blk.w + blk.w - 1, j = (blk.w << 1) - 1; j >= 0; k--) { barr[k] = (SupportClass.URShift(((((buf[j--] & 0xFF) << 8) | (buf[j--] & 0xFF)) << paddingLength), paddingLength)) - levShift; } break; case CSJ2K.j2k.io.EndianType_Fields.BIG_ENDIAN: for (k = (i - blk.uly) * blk.w + blk.w - 1, j = (blk.w << 1) - 1; j >= 0; k--) { barr[k] = (SupportClass.URShift((((buf[j--] & 0xFF) | ((buf[j--] & 0xFF) << 8)) << paddingLength), paddingLength)) - levShift; } break; default: throw new System.ApplicationException("Internal JJ2000 bug"); } } } break; case 4: // Samples packed into 4 bytes // Read line by line mi = blk.uly + blk.h; if (isSigned) { for (i = blk.uly; i < mi; i++) { // Reposition in input in_Renamed.Seek(offset + 4 * (i * w + blk.ulx), System.IO.SeekOrigin.Begin); in_Renamed.Read(buf, 0, blk.w << 2); switch (byteOrder) { case CSJ2K.j2k.io.EndianType_Fields.LITTLE_ENDIAN: for (k = (i - blk.uly) * blk.w + blk.w - 1, j = (blk.w << 2) - 1; j >= 0; k--) { barr[k] = ((((buf[j--] & 0xFF) << 24) | ((buf[j--] & 0xFF) << 16) | ((buf[j--] & 0xFF) << 8) | (buf[j--] & 0xFF)) << paddingLength) >> paddingLength; } break; case CSJ2K.j2k.io.EndianType_Fields.BIG_ENDIAN: for (k = (i - blk.uly) * blk.w + blk.w - 1, j = (blk.w << 2) - 1; j >= 0; k--) { barr[k] = (((buf[j--] & 0xFF) | ((buf[j--] & 0xFF) << 8) | ((buf[j--] & 0xFF) << 16) | ((buf[j--] & 0xFF) << 24)) << paddingLength) >> paddingLength; } break; default: throw new System.ApplicationException("Internal JJ2000 bug"); } } } else { for (i = blk.uly; i < mi; i++) { // Reposition in input in_Renamed.Seek(offset + 4 * (i * w + blk.ulx), System.IO.SeekOrigin.Begin); in_Renamed.Read(buf, 0, blk.w << 2); switch (byteOrder) { case CSJ2K.j2k.io.EndianType_Fields.LITTLE_ENDIAN: for (k = (i - blk.uly) * blk.w + blk.w - 1, j = (blk.w << 2) - 1; j >= 0; k--) { barr[k] = (SupportClass.URShift(((((buf[j--] & 0xFF) << 24) | ((buf[j--] & 0xFF) << 16) | ((buf[j--] & 0xFF) << 8) | (buf[j--] & 0xFF)) << paddingLength), paddingLength)) - levShift; } break; case CSJ2K.j2k.io.EndianType_Fields.BIG_ENDIAN: for (k = (i - blk.uly) * blk.w + blk.w - 1, j = (blk.w << 2) - 1; j >= 0; k--) { barr[k] = (SupportClass.URShift((((buf[j--] & 0xFF) | ((buf[j--] & 0xFF) << 8) | ((buf[j--] & 0xFF) << 16) | ((buf[j--] & 0xFF) << 24)) << paddingLength), paddingLength)) - levShift; } break; default: throw new System.ApplicationException("Internal JJ2000 bug"); } } } break; default: throw new System.IO.IOException("PGX supports only bit-depth between" + " 1 and 31"); } } catch (System.IO.IOException e) { JJ2KExceptionHandler.handleException(e); } // Turn off the progressive attribute blk.progressive = false; // Set buffer attributes blk.offset = 0; blk.scanw = blk.w; return(blk); }
/// <summary> Returns, in the blk argument, the block of image data containing the /// specifed rectangular area, in the specified component. The data is /// returned, as a reference to the internal data, if any, instead of as a /// copy, therefore the returned data should not be modified. /// /// <P> After being read the coefficients are level shifted by subtracting /// 2^(nominal bit range - 1) /// /// <P>The rectangular area to return is specified by the 'ulx', 'uly', 'w' /// and 'h' members of the 'blk' argument, relative to the current /// tile. These members are not modified by this method. The 'offset' and /// 'scanw' of the returned data can be arbitrary. See the 'DataBlk' class. /// /// <P>If the data array in <tt>blk</tt> is <tt>null</tt>, then a new one /// is created if necessary. The implementation of this interface may /// choose to return the same array or a new one, depending on what is more /// efficient. Therefore, the data array in <tt>blk</tt> prior to the /// method call should not be considered to contain the returned data, a /// new array may have been created. Instead, get the array from /// <tt>blk</tt> after the method has returned. /// /// <P>The returned data always has its 'progressive' attribute unset /// (i.e. false). /// /// <P>When an I/O exception is encountered the JJ2KExceptionHandler is /// used. The exception is passed to its handleException method. The action /// that is taken depends on the action that has been registered in /// JJ2KExceptionHandler. See JJ2KExceptionHandler for details. /// /// </summary> /// <param name="blk">Its coordinates and dimensions specify the area to /// return. Some fields in this object are modified to return the data. /// /// </param> /// <param name="c">The index of the component from which to get the data. Only 0 /// is valid. /// /// </param> /// <returns> The requested DataBlk /// /// </returns> /// <seealso cref="getCompData"> /// /// </seealso> /// <seealso cref="JJ2KExceptionHandler"> /// /// </seealso> public override DataBlk getInternCompData(DataBlk blk, int c) { int k, j, i, mi; int[] barr; // Check component index if (c != 0) { throw new System.ArgumentException(); } // Check type of block provided as an argument if (blk.DataType != DataBlk.TYPE_INT) { if (intBlk == null) { intBlk = new DataBlkInt(blk.ulx, blk.uly, blk.w, blk.h); } else { intBlk.ulx = blk.ulx; intBlk.uly = blk.uly; intBlk.w = blk.w; intBlk.h = blk.h; } blk = intBlk; } // Get data array barr = (int[])blk.Data; if (barr == null || barr.Length < blk.w * blk.h) { barr = new int[blk.w * blk.h]; blk.Data = barr; } // Check line buffer if (buf == null || buf.Length < blk.w) { buf = new byte[blk.w]; } try { // Read line by line mi = blk.uly + blk.h; for (i = blk.uly; i < mi; i++) { // Reposition in input in_Renamed.Seek(offset + i * w + blk.ulx, System.IO.SeekOrigin.Begin); in_Renamed.Read(buf, 0, blk.w); for (k = (i - blk.uly) * blk.w + blk.w - 1, j = blk.w - 1; j >= 0; j--, k--) { barr[k] = (((int)buf[j]) & 0xFF) - DC_OFFSET; } } } catch (System.IO.IOException e) { JJ2KExceptionHandler.handleException(e); } // Turn off the progressive attribute blk.progressive = false; // Set buffer attributes blk.offset = 0; blk.scanw = blk.w; return(blk); }