All Downloads are FREE. Search and download functionalities are using the official Maven repository.

ucar.jpeg.jj2000.j2k.image.output.ImgWriterArray.working Maven / Gradle / Ivy

The newest version!
/*
 * CVS identifier:
 *
 * $Id: ImgWriterArray.java,v 1.0 2004/11/02 14:10:46 rkambic Exp $
 *
 * Class:                   ImgWriterArray
 *
 * Description:             Image Writer for Array format
 *
 *
 *
 * */
package jj2000.j2k.image.output;

import jj2000.j2k.image.*;
import jj2000.j2k.util.*;

import java.io.*;

/**
 * This class extends the ImgWriter abstract class for writing Array .  Array
 * is a custom monochrome format invented specifically to simplify the
 * use of VM3A with images of different bit-depths in the range 1 to 31 bits
 * per pixel.
 *
 * 

The file consists of a one line text header followed by the data.

* *

* Header: "PG"+ ws +<endianess>+ ws * +[sign]+ws + <bit-depth>+" * "+<width>+" "+<height>+'\n'

* *

where:
*

    *
  • ws (white-spaces) is any combination of characters ' ' and * '\t'.
  • *
  • endianess equals "LM" or "ML"(resp. little-endian or * big-endian)
  • *
  • sign equals "+" or "-" (resp. unsigned or signed). If omited, * values are supposed to be unsigned.
  • *
  • bit-depth that can be any number between 1 and 31.
  • *
  • width and height are the image dimensions (in * pixels).
  • *
* * Data: The image binary values appear one after the other (in raster * order) immediately after the last header character ('\n') and are * byte-aligned (they are packed into 1,2 or 4 bytes per sample, depending * upon the bit-depth value). *

* *

If the data is unsigned, level shifting is applied adding 2^(bit depth * - 1)

* *

NOTE: This class is not thread safe, for reasons of internal * buffering.

* * @see ImgWriter * * @see BlkImgDataSrc * */ public class ImgWriterArray extends ImgWriter { /** Used during saturation (2^bitdepth-1 if unsigned, 2^(bitdepth-1)-1 if * signed)*/ int maxVal; /** Used during saturation (0 if unsigned, -2^(bitdepth-1) if signed) */ int minVal; /** Used with level-shiting */ int levShift; /** Whether the data must be signed when writing or not. In the latter * case inverse level shifting must be applied */ boolean isSigned; /** The bit-depth of the input file (must be between 1 and 31)*/ private int bitDepth; /** Where to write the data */ //private RandomAccessFile out; /** The offset of the raw pixel data in the Array file */ private int offset; /** A DataBlk, just used to avoid allocating a new one each time it is needed */ private DataBlkInt db = new DataBlkInt(); /** The number of fractional bits in the source data */ private int fb; /** The index of the component from where to get the data */ private int c; /** The pack length of one sample (in bytes, according to the output bit-depth */ private int packBytes; /** data array for Grib2 */ private int gdata[]; /** The line buffer. */ // This makes the class not thread safe // (but it is not the only one making it so) private byte buf[]; /** * Creates a new writer to the specified File object, to write data from * the specified component. * *

The size of the image that is written to the file is the size of the * component from which to get the data, specified by b, not the size of * the source image (they differ if there is some sub-sampling).

* *

All the header informations are given by the BlkImgDataSrc source * (component width, component height, bit-depth) and sign flag, which are * provided to the constructor. The endianness is always big-endian (MSB * first).

* * @param out The file where to write the data * * @param imgSrc The source from where to get the image data to write. * * @param c The index of the component from where to get the data. * * @param isSigned Whether the datas are signed or not (needed only when * writing header). * * @see DataBlk * */ public ImgWriterArray(BlkImgDataSrc imgSrc, int c, boolean isSigned) throws IOException { //Initialize this.c = c; this.isSigned = isSigned; //System.out.println("sign = " + isSigned ); src = imgSrc; w = src.getImgWidth(); h = src.getImgHeight(); fb = imgSrc.getFixedPoint(c); System.out.println(" constructor iwa w=" + w +" h=" +h +" Fixedpt=" + fb ) ; bitDepth = src.getNomRangeBits(this.c); if((bitDepth<=0)||(bitDepth>31)) { throw new IOException("Array supports only bit-depth between "+ "1 and 31"); } if(bitDepth<=8) { packBytes = 1; } else if(bitDepth<=16) { packBytes = 2; } else { // <= 31 packBytes = 4; } System.out.println("data size=" + (h * w * packBytes)); gdata = new int[ h * w * packBytes ]; //gdata = new int[ h * w ]; // Writes Array header //String tmpString = "PG " // + "ML " // Always writing big-endian // + ((this.isSigned) ? "- " : "+ ") // signed/unsigned // + bitDepth + " " // bit-depth //+ w + " " // component width //+ h + "\n"; // component height //byte[] tmpByte = tmpString.getBytes(); //for(int i=0; i0; i--) { // out.writeByte(0); // System.out.println("close filling file w/ 0's" ); //} //} //out.close(); src = null; //out = null; //db = null; } /** * Writes the data of the specified area to the file, coordinates are * relative to the current tile of the source. Before writing, the * coefficients are limited to the nominal range and packed into 1,2 or 4 * bytes (according to the bit-depth). * *

If the data is unisigned, level shifting is applied adding 2^(bit * depth - 1)

* *

This method may not be called concurrently from different * threads.

* *

If the data returned from the BlkImgDataSrc source is progressive, * then it is requested over and over until it is not progressive * anymore.

* * @param ulx The horizontal coordinate of the upper-left corner of the * area to write, relative to the current tile. * * @param uly The vertical coordinate of the upper-left corner of the area * to write, relative to the current tile. * * @param width The width of the area to write. * * @param height The height of the area to write. * * @exception IOException If an I/O error occurs. * */ public void write(int ulx, int uly, int w, int h) throws IOException { int k,i,j; int fracbits = fb; // In local variable for faster access int tOffx, tOffy; // Active tile offset in the X and Y direction //System.out.println( " ulx=" + ulx +" uly=" + uly +" w=" + w +" h=" + h); // Initialize db db.ulx = ulx; db.uly = uly; db.w = w; db.h = h; //db.ulx = 0; //db.uly = 0; //db.w = 614; //db.h = 428; // Get the current active tile offset tOffx = src.getCompULX(c)- (int)Math.ceil(src.getImgULX()/(double)src.getCompSubsX(c)); tOffy = src.getCompULY(c)- (int)Math.ceil(src.getImgULY()/(double)src.getCompSubsY(c)); // Check the array size if(db.data!=null && db.data.length=0; k--) { tmp = db.data[k]+levShift; tmp = (tmpmaxVal)? maxVal: tmp); buf[j--] = (byte)tmp; // No need to use 0xFF buf[j--] = (byte)(tmp>>>8); // masks since truncation buf[j--] = (byte)(tmp>>>16); // will have already the buf[j--] = (byte)(tmp>>>24); // same effect } } else { for(k=db.offset+i*db.scanw+w-1, j=(w<<2)-1; j>=0; k--) { tmp = (db.data[k]>>>fracbits)+levShift; tmp = (tmpmaxVal)? maxVal: tmp); buf[j--] = (byte)tmp; // No need to use 0xFF buf[j--] = (byte)(tmp>>>8); // masks since truncation buf[j--] = (byte)(tmp>>>16); // will have already the buf[j--] = (byte)(tmp>>>24); // same effect } } //out.write(buf,0,w<<2); } break; default: throw new IOException("Array supports only bit-depth between "+ "1 and 31"); } } public void writeAll() throws IOException { // Find the list of tile to decode. Coord nT = src.getNumTiles(null); System.out.println( "ImgWriterArray nTiles = " + nT ); // Loop on vertical tiles for(int y=0; yIf the data returned from the BlkImgDataSrc source is progressive, * then it is requested over and over until it is not progressive * anymore.

* * @exception IOException If an I/O error occurs. * * @see DataBlk * */ public void write() throws IOException { int i; int tIdx = src.getTileIdx(); int tw = src.getTileCompWidth(tIdx,c); // Tile width int th = src.getTileCompHeight(tIdx,c); // Tile height // Write in strips for(i=0; i




© 2015 - 2025 Weber Informatics LLC | Privacy Policy