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

gov.nasa.worldwind.formats.nitfs.NITFSImageSegment Maven / Gradle / Ivy

The newest version!
/*
 * Copyright (C) 2012 United States Government as represented by the Administrator of the
 * National Aeronautics and Space Administration.
 * All Rights Reserved.
 */
package gov.nasa.worldwind.formats.nitfs;

import gov.nasa.worldwind.formats.rpf.*;
import gov.nasa.worldwind.geom.LatLon;

import java.nio.*;

/**
 * @author Lado Garakanidze
 * @version $Id: NITFSImageSegment.java 1171 2013-02-11 21:45:02Z dcollins $
 */
public class NITFSImageSegment extends NITFSSegment
{
    public static final String[] SupportedFormats = { "CIB", "CADRG", "ADRG" };
    // [ nitf identification , security, structure fields]
    public String partType;
    public String imageID;
    public String dateTime;
    public String targetID;
    public String imageTitle;
    public String securityClass;
    public String codewords;
    public String controlAndHandling;
    public String releaseInstructions;
    public String classAuthority;
    public String securityCtrlNum;
    public String ISDWNG;                       // image security downgrade
    public String ISDEVT;                       // downgrading event
    public short  encryption;
    public String imageSource;
    public int    numSignificantRows;
    public int    numSignificantCols;
    public String pixelValueType;
    public String imageRepresentation;
    public String imageCategory;
    public short  bitsPerPixelPerBand;
    public String pixelJustification;
    public String imageCoordSystem;
    // [ nitf image geographic location ]
    public LatLon[] imageCoords;
    // [ nitf comments ]
    public String[] imageCommentRecords;
    // [ nitf image compression structure ]
    public String imageCompression;
    public String compressionRateCode;
    public short    NBANDS;                     // number of bands { 1 for MONO and RGB/LUT, 3 for RGB;
    // [ nitfs image bands ]
    public NITFSImageBand[] imageBands;
    // [ nitf image table structure fields ]
    public short    imageSyncCode;              // ISYNC { 0 - No sync code, 1 - sync code }
    public String   imageMode;                  // IMODE { B, P, R, S }
    public short    numOfBlocksPerRow;          // NBPR   { 0001~9999 }
    public short    numOfBlocksPerCol;          // NBPC   { 0001~9999 }
    public short    numOfPixelsPerBlockH;       // NPPBH  { 0001~8192 }
    public short    numOfPixelsPerBlockV;       // NPPBV  { 0001~8192 }
    public short    numOfBitsPerPixelPerBand;   // NBPP   { 01~96 }
    public short    displayLevel;               // IDLVL  { 001~999 }
    public short    attachmentLevel;            // IALVL  { 001~998 }
    // [ nitfs image location ]
    public short    imageRowOffset;             // ILOC   { -0001 ~ +9999 }
    public short    imageColOffset;             //

    // [ nitf image magnification ]
    public String   imageMagnification;         // IMAG
    public short    userDefinedSubheaderLength;

    // [ nitf user-defined image subheader ]
    private UserDefinedImageSubheader userDefSubheader;

    // [ nitf-rpf image display parameter sub-header ]
    private long    numOfImageRows;
    private long    numOfImageCodesPerRow;
    private short   imageCodeBitLength;

    // [ nitf rpf compression section ]
    //      [ nitf-rpf compression section sub-header ]
    private int     compressionAlgorithmID;
    private int     numOfCompressionLookupOffsetRecords;
    private int     numOfCompressionParameterOffsetRecords;

    //      [ nitf rpf compression lookup sub-section ]
    private long    compressionLookupOffsetTableOffset;
    private int     compressionLookupTableOffsetRecordLength;


    // [ nitf-rpf mask subsection ]
    private int     subframeSequenceRecordLength;
    private int     transparencySequenceRecordLength;
    private int     transparentOutputPixelCodeLength;
    private int     transparentOutputPixelCode;
    private int[]   subFrameOffsets = null;

    private boolean hasTransparentPixels = false;
    private boolean hasMaskedSubframes = false;

    public static String[] getSupportedFormats()
    {
        return SupportedFormats;
    }

    public boolean hasTransparentPixels()
    {
        return this.hasTransparentPixels;
    }

    public boolean hasMaskedSubframes()
    {
        return this.hasMaskedSubframes;
    }

    private CompressionLookupRecord[] compressionLUTS;

    public UserDefinedImageSubheader getUserDefinedImageSubheader()
    {
        return userDefSubheader;
    }

    public RPFFrameFileComponents getRPFFrameFileComponents()
    {
        return (null != userDefSubheader) ? userDefSubheader.getRPFFrameFileComponents() : null;
    }

    public NITFSImageSegment(java.nio.ByteBuffer buffer, int headerStartOffset, int headerLength,int dataStartOffset, int dataLength)
    {
        super(NITFSSegmentType.IMAGE_SEGMENT, buffer, headerStartOffset, headerLength, dataStartOffset, dataLength);

        int saveOffset = buffer.position();

        buffer.position( headerStartOffset );
        // do not change order of parsing
        this.parseIdentificationSecurityStructureFields(buffer);
        this.parseImageGeographicLocation(buffer);
        this.parseCommentRecords(buffer);
        this.parseImageCompressionStructure(buffer);
        this.parseImageBands(buffer);
        this.parseImageTableStructure(buffer);
        this.parseImageLocation(buffer);
        this.parseImageSubheaders(buffer);
        this.parseImageData(buffer);
        this.validateImage();

        buffer.position(saveOffset); // last line - restore buffer's position
    }

    private void decompressBlock4x4(byte[][] block4x4, short code)
    {
        this.compressionLUTS[0].copyValues(block4x4[0], 0, code, 4);
        this.compressionLUTS[1].copyValues(block4x4[1], 0, code, 4);
        this.compressionLUTS[2].copyValues(block4x4[2], 0, code, 4);
        this.compressionLUTS[3].copyValues(block4x4[3], 0, code, 4);
    }

    private void decompressBlock16(byte[] block16, short code)
    {
        this.compressionLUTS[0].copyValues(block16,  0, code, 4);
        this.compressionLUTS[1].copyValues(block16,  4, code, 4);
        this.compressionLUTS[2].copyValues(block16,  8, code, 4);
        this.compressionLUTS[3].copyValues(block16, 12, code, 4);
    }

    public int[] getImagePixelsAsArray(int[] pixels, RPFImageType imageType) throws NITFSRuntimeException {
        RPFFrameFileComponents rpfComponents = this.getRPFFrameFileComponents();
        RPFLocationSection componentLocationTable = rpfComponents.componentLocationTable;

        int spatialDataSubsectionLocation = componentLocationTable.getSpatialDataSubsectionLocation();
        super.buffer.position( spatialDataSubsectionLocation );

        int band = 0; // for(int band = 0; band < rpfComponents.numOfSpectralBandTables;  band++)
        NITFSImageBand imageBand = this.imageBands[band];

        int rgbColor, colorCode;
        short aa, ab, bb;
        short[] codes = new short[(int) this.numOfImageCodesPerRow];
        byte[][] block4x4 = new byte[4][4];
        int rowSize = (short) ((this.numOfImageCodesPerRow * this.imageCodeBitLength) / 8L);
        byte[] rowBytes = new byte[rowSize];
        int subFrameOffset;
        short subFrameIdx = 0;

        for (int subFrameH = 0; subFrameH < this.numOfBlocksPerCol; subFrameH++)
        {
            for (int subFrameW = 0; subFrameW < this.numOfBlocksPerRow; subFrameW++, subFrameIdx++ )
            {
                int blockY = (int) (subFrameH * rpfComponents.numOfOutputRowsPerSubframe);
                int blockX = (int) (subFrameW * rpfComponents.numOfOutputColumnsPerSubframe);

                if(hasMaskedSubframes)
                {
                    subFrameOffset = this.subFrameOffsets[subFrameIdx];
                    if( -1 == subFrameOffset)
                    {   // this is a masked / empty subframe
                        continue;
                    }
                    else
                    {
                        super.buffer.position( spatialDataSubsectionLocation + subFrameOffset );
                    }
                }

                for (int row = 0; row < this.numOfImageRows; row++)
                {
                    int qy = blockY + row * 4;

                    super.buffer.get(rowBytes, 0, rowSize);

                    // short[] codes = new short[(int) this.numOfImageCodesPerRow];
                    for (int i = 0, cidx = 0, bidx = 0; i < (int) this.numOfImageCodesPerRow / 2; i++)
                    {
                        aa = (short) ((0x00FF & (short) rowBytes[bidx++]) << 4);
                        ab = (short) (0x00FF & (short)  rowBytes[bidx++]);
                        bb = (short) (0x00FF & (short)  rowBytes[bidx++]);

                        codes[cidx++] = (short) (aa | ((0x00F0 & ab) >> 4));
                        codes[cidx++] = (short) (bb | ((0x000F & ab) << 8));
                    }

                    for (int col = 0; col < this.numOfImageCodesPerRow; col++)
                    {
                        if (hasTransparentPixels)
                        {
                            if (4095 == codes[col])
                            {   // this is a transparent kernel
                                continue;                          
                            }
                        }

                        this.decompressBlock4x4( block4x4, codes[col] );

                        int qx = blockX + col * 4;

                        for (int h = 0; h < 4; h++)
                        {
                            for (int w = 0; w < 4; w++)
                            {
                                colorCode = 0x00FF & block4x4[h][w];

                                if (hasTransparentPixels)
                                {
                                    if (this.transparentOutputPixelCode == colorCode)
                                    {   // this is a transparent pixel
                                        continue;
                                    }
                                }

                                if (imageBand.isReservedApplicationCode(colorCode))
                                {
                                    // This is a reserved color code used to define an application-specific overlay. We
                                    // don't know the meaning of application overlay codes, therefore we treat them as
                                    // transparent or background pixels.
                                    continue;
                                }

                                rgbColor = imageBand.lookupRGB(colorCode);
                                switch (imageType)
                                {
                                    case IMAGE_TYPE_ALPHA_RGB:
                                        rgbColor = 0xFF000000 + rgbColor;
                                        break;
                                  //case IMAGE_TYPE_GRAY:
                                  //    break;
                                  //case IMAGE_TYPE_RGB:
                                  //    break;
                                    case IMAGE_TYPE_GRAY_ALPHA:
                                        rgbColor = (rgbColor << 8) + 0xFF;
                                        break;
                                    case IMAGE_TYPE_RGB_ALPHA:
                                        rgbColor = (rgbColor << 8) + 0xFF;
                                        break;
                                }
                                pixels[(qy + h) * this.numSignificantCols + (qx + w)] = rgbColor;
                            }
                        }
                    } // end of column loop
                } // end of row loop
            } // end of subFrameW loop
        } // end of subFrameH loop

        return pixels;
    }

    private void validateImage() throws NITFSRuntimeException {
        RPFFrameFileComponents rpfComponents = this.getRPFFrameFileComponents();

        if(1 != this.compressionAlgorithmID )
            throw new NITFSRuntimeException("NITFSReader.UnsupportedCompressionAlgorithm");
        if( ! "B".equals(this.imageMode) )
            throw new NITFSRuntimeException("NITFSReader.UnsupportedImageMode");
        if( 1 != rpfComponents.numOfSpectralGroups )
            throw new NITFSRuntimeException("NITFSReader.UnsupportedNumberOfSpectralGroups.");
        if( 12 != this.imageCodeBitLength )
            throw new NITFSRuntimeException("NITFSReader.UnsupportedImageCodeBitLength.");



        
    }

    private void parseRPFMaskSubsection(java.nio.ByteBuffer buffer) throws NITFSRuntimeException {
        // parse [ nitf-rpf mask subsection ]
        int maskSubsectionPos = buffer.position(); // mark the [ nitf-rpf mask subsection ] offset
        int subframeMaskTableOffset = (int) this.getRPFFrameFileComponents().subframeMaskTableOffset;
        int transparencyMaskTableOffset = (int) this.getRPFFrameFileComponents().transparencyMaskTableOffset;

        this.subframeSequenceRecordLength = NITFSUtil.getUShort(buffer);
        this.transparencySequenceRecordLength = NITFSUtil.getUShort(buffer);
        this.transparentOutputPixelCodeLength = NITFSUtil.getUShort(buffer);

        if( 0 != this.transparentOutputPixelCodeLength )
        {
            String bitstr = NITFSUtil.getBitString(buffer, this.transparentOutputPixelCodeLength);
            this.transparentOutputPixelCode = Integer.parseInt(bitstr, 2);
        }

        // parse [ nitf-rpf subframe mask table ]
        if(-1 != subframeMaskTableOffset || 0 < this.subframeSequenceRecordLength)
        {
            // seek to [ subframe mask table offset ]
            if (-1 != subframeMaskTableOffset)
                buffer.position(maskSubsectionPos + subframeMaskTableOffset);

            RPFFrameFileComponents rpfComponents = this.getRPFFrameFileComponents();
            subFrameOffsets = new int[ this.numOfBlocksPerCol * this.numOfBlocksPerRow ];
            // parse [ nitf-rpf subframe mask table ]
            int idx = 0;
            for(int group = 0 ; group < rpfComponents.numOfSpectralGroups; group++ )
            {
                for(int row = 0 ; row < this.numOfBlocksPerCol; row++ )
                {
                    for(int col = 0 ; col < this.numOfBlocksPerRow; col++ )
                        subFrameOffsets[idx++] = (int) NITFSUtil.getUInt(buffer);
                }
            }
        }
        else
        {
            this.subFrameOffsets = null;
        }

        // parse [ nitf-rpf transparency mask table ]        
        if (-1 != transparencyMaskTableOffset || 0 < this.transparencySequenceRecordLength)
        {
        }

        this.hasMaskedSubframes = (null != this.subFrameOffsets && 0 < this.subFrameOffsets.length);
        this.hasTransparentPixels = (0 < this.transparencySequenceRecordLength || 0 < this.transparentOutputPixelCodeLength);
    }


    private void parseImageData(java.nio.ByteBuffer buffer) throws NITFSRuntimeException {
        RPFLocationSection componentLocationTable = this.getRPFFrameFileComponents().componentLocationTable;

        buffer.position(this.dataStartOffset);
        long spatialDataOffset = NITFSUtil.getUInt(buffer);

        if(0 < componentLocationTable.getMaskSubsectionLength())
        {
            // parse nitf-rpf mask subsection
            buffer.position( componentLocationTable.getMaskSubsectionLocation() );
            this.parseRPFMaskSubsection(buffer);
        }

        if(0 < componentLocationTable.getImageDisplayParametersSubheaderLength())
        {   // parse [ nitf-rpf image display parameter sub-header ]
            buffer.position( componentLocationTable.getImageDisplayParametersSubheaderLocation() );
            this.parseImageDisplayParametersSubheader(buffer);
        }
        else
            throw new NITFSRuntimeException("NITFSReader.ImageDisplayParametersSubheaderNotFound");

        // [ nitf rpf compression section ]
        if(0 < componentLocationTable.getCompressionSectionSubheaderLength())
        {   // parse [ nitf-rpf compression section sub-header ]
            buffer.position( componentLocationTable.getCompressionSectionSubheaderLocation() );
            this.parseRPFCompressionSectionSubheader(buffer);
        }
        else
            throw new NITFSRuntimeException("NITFSReader.RPFCompressionSectionSubheaderNotFound");

        // [ nitf rpf compression lookup sub-section ]
        if(0 < componentLocationTable.getCompressionLookupSubsectionLength())
        {
            buffer.position( componentLocationTable.getCompressionLookupSubsectionLocation() );
            this.parseRPFCompressionLookupSubsection(buffer);
        }
        else
            throw new NITFSRuntimeException("NITFSReader.RPFCompressionLookupSubsectionNotFound");

        // [ nitf rpf compression parameter subsection ]
        if(0 < componentLocationTable.getCompressionParameterSubsectionLength())
            throw new NITFSRuntimeException("NITFSReader.RPFCompressionParameterSubsectionNotImplemented");

        // [ nitf rpf spatial data subsection ]
        if(0 < componentLocationTable.getSpatialDataSubsectionLength())
        {

            buffer.position( componentLocationTable.getSpatialDataSubsectionLocation() );
            this.parseRPFSpatialDataSubsection(buffer);
        }
        else
            throw new NITFSRuntimeException("NITFSReader.RPFSpatialDataSubsectionNotFound");
    }

    private void parseRPFSpatialDataSubsection(java.nio.ByteBuffer buffer) throws NITFSRuntimeException {
        

    }

    private void parseRPFCompressionLookupSubsection(java.nio.ByteBuffer buffer)
        throws NITFSRuntimeException {
        int compressionLookupSubsectionLocation = buffer.position();
        // [ nitf rpf compression lookup sub-section ]
        this.compressionLookupOffsetTableOffset = NITFSUtil.getUInt(buffer);
        this.compressionLookupTableOffsetRecordLength = NITFSUtil.getUShort(buffer);

        this.compressionLUTS = new CompressionLookupRecord[this.numOfCompressionLookupOffsetRecords];
        for(int i = 0 ; i < this.numOfCompressionLookupOffsetRecords; i++)
        {
            this.compressionLUTS[i] = new CompressionLookupRecord( buffer,
                compressionLookupSubsectionLocation,
                this.getRPFFrameFileComponents().rpfColorMaps);
        }
    }

    private void parseRPFCompressionSectionSubheader(java.nio.ByteBuffer buffer) throws NITFSRuntimeException {
        // parse [ nitf-rpf compression section sub-header ]
        this.compressionAlgorithmID = NITFSUtil.getUShort(buffer);
        this.numOfCompressionLookupOffsetRecords = NITFSUtil.getUShort(buffer);
        this.numOfCompressionParameterOffsetRecords = NITFSUtil.getUShort(buffer);
    }

    private void parseImageDisplayParametersSubheader(java.nio.ByteBuffer buffer) throws NITFSRuntimeException {
        // parse [ nitf-rpf image display parameter sub-header ]
        this.numOfImageRows = NITFSUtil.getUInt(buffer);
        this.numOfImageCodesPerRow = NITFSUtil.getUInt(buffer);
        this.imageCodeBitLength = NITFSUtil.getByteAsShort(buffer);
    }
    
    private void parseImageSubheaders(java.nio.ByteBuffer buffer) throws NITFSRuntimeException {
        this.userDefinedSubheaderLength = NITFSUtil.getShortNumeric(buffer, 5);
        if (0 == this.userDefinedSubheaderLength)
        {
            this.userDefSubheader = null;
            return;
        }
        
        this.userDefSubheader = new UserDefinedImageSubheader(buffer);
    }
    private void parseImageLocation(java.nio.ByteBuffer buffer) throws NITFSRuntimeException {
        this.imageRowOffset = NITFSUtil.getShortNumeric(buffer, 5);
        this.imageColOffset = NITFSUtil.getShortNumeric(buffer, 5);
        // [ nitf image magnification ]
        this.imageMagnification = NITFSUtil.getString(buffer, 4);
   }

    private void parseImageTableStructure(java.nio.ByteBuffer buffer) throws NITFSRuntimeException {
        this.imageSyncCode = NITFSUtil.getShortNumeric(buffer, 1);
        this.imageMode = NITFSUtil.getString(buffer, 1);
        this.numOfBlocksPerRow = NITFSUtil.getShortNumeric(buffer, 4);
        this.numOfBlocksPerCol = NITFSUtil.getShortNumeric(buffer, 4);
        this.numOfPixelsPerBlockH = NITFSUtil.getShortNumeric(buffer, 4);
        this.numOfPixelsPerBlockV = NITFSUtil.getShortNumeric(buffer, 4);
        this.numOfBitsPerPixelPerBand = NITFSUtil.getShortNumeric(buffer, 2);
        this.displayLevel = NITFSUtil.getShortNumeric(buffer, 3);
        this.attachmentLevel = NITFSUtil.getShortNumeric(buffer, 3);
    }

    private void parseImageBands(java.nio.ByteBuffer buffer) throws NITFSRuntimeException {
        if(0 == this.NBANDS)
            throw new NITFSRuntimeException("NITFSReader.InvalidNumberOfImageBands");
        this.imageBands = new NITFSImageBand[this.NBANDS];
        for(int i = 0 ; i < this.NBANDS; i++)
            this.imageBands[i] = new NITFSImageBand(buffer);
    }
    private void parseImageCompressionStructure(java.nio.ByteBuffer buffer)
    {
        this.imageCompression = NITFSUtil.getString(buffer, 2);
        this.compressionRateCode = NITFSUtil.getString(buffer, 4);
        this.NBANDS = NITFSUtil.getShortNumeric(buffer, 1);
    }

    private void parseCommentRecords(java.nio.ByteBuffer buffer)
    {
        int numCommentRecords = NITFSUtil.getShortNumeric(buffer, 1);
        if(0 < numCommentRecords)
        {
            this.imageCommentRecords = new String[numCommentRecords];
            for(int i = 0; i < numCommentRecords; i++)
                this.imageCommentRecords[i] = NITFSUtil.getString(buffer, 80);
        }
        else
            this.imageCommentRecords = null;
    }

    private void parseImageGeographicLocation(java.nio.ByteBuffer buffer)
    {
        // [ nitf image geographic location ]
        // four lat/lon coordinates encoded as ddmmssXdddmmssY
        // (some CADRG files encode coordinates as ddmmssXddmmssY0)
        int coordLen = 15; // each coordinate is 15 bytes
        byte[] dst = new byte[coordLen];
        ByteBuffer dstBuffer;

        String hemisphere;
        double deg, min, sec, lat, lon;
        double sixty = 60.0;
        this.imageCoords = new LatLon[4];
        for (int i = 0; i < 4; i++)
        {
            buffer.get(dst, 0, coordLen);
            dstBuffer = ByteBuffer.wrap(dst, 0, coordLen);

            // parse latitude [ ddmmssX ]
            deg = (double) NITFSUtil.getShortNumeric(dstBuffer, 2);
            min = (double) NITFSUtil.getShortNumeric(dstBuffer, 2);
            sec = (double) NITFSUtil.getShortNumeric(dstBuffer, 2);
            hemisphere = NITFSUtil.getString(dstBuffer, 1);
            lat = deg + (min + (sec / sixty)) / sixty;   // decimal latitude
            if("S".equals(hemisphere))
                lat *= -1.0;

            // parse longitude [ dddmmssY ]
            int londegLen = dst[14] != 0 ? 3 : 2; // handle the case when longitude is encoded as ddmmssY
            deg = (double) NITFSUtil.getShortNumeric(dstBuffer, londegLen);
            min = (double) NITFSUtil.getShortNumeric(dstBuffer, 2);
            sec = (double) NITFSUtil.getShortNumeric(dstBuffer, 2);
            hemisphere = NITFSUtil.getString(dstBuffer, 1);
            lon = deg + (min + (sec / sixty)) / sixty;   // decimal longitude
            if("W".equals(hemisphere))
                lon *= -1.0;

            // TODO Do not waste time on this calculations - the same info is repeated in the [ rpf coverage section ]
            // TODO zz: garakl: convert to LatLon according to the CoordinateSystem
            // if(0 == StringUtil.compare(imageCoordSystem, "G"))
            this.imageCoords[i] = LatLon.fromDegrees(lat, lon);
        }
    }

    private void parseIdentificationSecurityStructureFields(java.nio.ByteBuffer buffer)
        throws NITFSRuntimeException {
        // [ nitf identification , security, structure fields]
        this.partType = NITFSUtil.getString(buffer, 2);
        if(!"IM".equals(this.partType))
            throw new NITFSRuntimeException("NITFSReader.UnexpectedSegmentType", this.partType);

        this.imageID = NITFSUtil.getString(buffer, 10);
        boolean isSupportedFormat = false;
        for(String s : SupportedFormats)
        {
            if(0 == s.compareTo(this.imageID))
            {
                isSupportedFormat = true;
                break;
            }
        }
        if(!isSupportedFormat)
            throw new NITFSRuntimeException("NITFSReader.UnsupportedImageFormat", this.imageID);

        this.dateTime = NITFSUtil.getString(buffer, 14);
        this.targetID = NITFSUtil.getString(buffer, 17);
        this.imageTitle = NITFSUtil.getString(buffer, 80);
        this.securityClass = NITFSUtil.getString(buffer, 1);
        this.codewords = NITFSUtil.getString(buffer, 40);
        this.controlAndHandling = NITFSUtil.getString(buffer, 40);
        this.releaseInstructions = NITFSUtil.getString(buffer, 40);
        this.classAuthority = NITFSUtil.getString(buffer, 20);              // ISCAUT
        this.securityCtrlNum = NITFSUtil.getString(buffer, 20);             // ISCTLN
        this.ISDWNG = NITFSUtil.getString(buffer, 6);
        this.ISDEVT = "999998".equals(this.ISDWNG) ? NITFSUtil.getString(buffer, 40) : "";
        
        this.encryption = NITFSUtil.getShortNumeric(buffer, 1);
        this.imageSource = NITFSUtil.getString(buffer, 42);
        this.numSignificantRows = NITFSUtil.getNumeric(buffer, 8);
        this.numSignificantCols = NITFSUtil.getNumeric(buffer, 8);
        this.pixelValueType = NITFSUtil.getString(buffer, 3);
        this.imageRepresentation = NITFSUtil.getString(buffer, 8);
        this.imageCategory = NITFSUtil.getString(buffer, 8);
        this.bitsPerPixelPerBand = NITFSUtil.getShortNumeric(buffer, 2);
        this.pixelJustification = NITFSUtil.getString(buffer, 1);
        this.imageCoordSystem = NITFSUtil.getString(buffer, 1);
    }

    
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy