1 package gov
.nasa
.worldwind
.formats
.nitfs
;
3 import gov
.nasa
.worldwind
.*;
4 import gov
.nasa
.worldwind
.formats
.rpf
.*;
5 import gov
.nasa
.worldwind
.geom
.*;
9 Copyright (C) 2001, 2007 United States Government
10 as represented by the Administrator of the
11 National Aeronautics and Space Administration.
16 * @author Lado Garakanidze
17 * @version $Id: NitfsImageSegment Mar 30, 2007 12:21:34 PM lado
19 public class NitfsImageSegment
extends NitfsSegment
21 public static final String
[] SupportedFormats
= { "CIB", "CADRG", "ADRG" };
22 // [ nitf identification , security, structure fields]
23 public String partType
;
24 public String imageID
;
25 public String dateTime
;
26 public String targetID
;
27 public String imageTitle
;
28 public String securityClass
;
29 public String codewords
;
30 public String controlAndHandling
;
31 public String releaseInstructions
;
32 public String classAuthority
;
33 public String securityCtrlNum
;
34 public String ISDWNG
; // image security downgrade
35 public String ISDEVT
; // downgrading event
36 public short encryption
;
37 public String imageSource
;
38 public int numSignificantRows
;
39 public int numSignificantCols
;
40 public String pixelValueType
;
41 public String imageRepresentation
;
42 public String imageCategory
;
43 public short bitsPerPixelPerBand
;
44 public String pixelJustification
;
45 public String imageCoordSystem
;
46 // [ nitf image geographic location ]
47 public LatLon
[] imageCoords
;
49 public String
[] imageCommentRecords
;
50 // [ nitf image compression structure ]
51 public String imageCompression
;
52 public String compressionRateCode
;
53 public short NBANDS
; // number of bands { 1 for MONO and RGB/LUT, 3 for RGB;
54 // [ nitfs image bands ]
55 public NitfsImageBand
[] imageBands
;
56 // [ nitf image table structure fields ]
57 public short imageSyncCode
; // ISYNC { 0 - No sync code, 1 - sync code }
58 public String imageMode
; // IMODE { B, P, R, S }
59 public short numOfBlocksPerRow
; // NBPR { 0001~9999 }
60 public short numOfBlocksPerCol
; // NBPC { 0001~9999 }
61 public short numOfPixelsPerBlockH
; // NPPBH { 0001~8192 }
62 public short numOfPixelsPerBlockV
; // NPPBV { 0001~8192 }
63 public short numOfBitsPerPixelPerBand
; // NBPP { 01~96 }
64 public short displayLevel
; // IDLVL { 001~999 }
65 public short attachmentLevel
; // IALVL { 001~998 }
66 // [ nitfs image location ]
67 public short imageRowOffset
; // ILOC { -0001 ~ +9999 }
68 public short imageColOffset
; //
70 // [ nitf image magnification ]
71 public String imageMagnification
; // IMAG
72 public short userDefinedSubheaderLength
;
74 // [ nitf user-defined image subheader ]
75 private UserDefinedImageSubheader userDefSubheader
;
77 // [ nitf-rpf image display parameter sub-header ]
78 private long numOfImageRows
;
79 private long numOfImageCodesPerRow
;
80 private short imageCodeBitLength
;
82 // [ nitf rpf compression section ]
83 // [ nitf-rpf compression section sub-header ]
84 private int compressionAlgorithmID
;
85 private int numOfCompressionLookupOffsetRecords
;
86 private int numOfCompressionParameterOffsetRecords
;
88 // [ nitf rpf compression lookup sub-section ]
89 private long compressionLookupOffsetTableOffset
;
90 private int compressionLookupTableOffsetRecordLength
;
93 // [ nitf-rpf mask subsection ]
94 private int subframeSequenceRecordLength
;
95 private int transparencySequenceRecordLength
;
96 private int transparentOutputPixelCodeLength
;
97 private byte[] transparentOutputPixelCode
;
98 private int[] subFrameOffsets
= null;
100 private boolean hasTransparentPixels
= false;
101 private boolean hasMaskedSubframes
= false;
103 public static String
[] getSupportedFormats()
105 return SupportedFormats
;
108 public boolean hasTransparentPixels()
110 return this.hasTransparentPixels
;
113 public boolean hasMaskedSubframes()
115 return this.hasMaskedSubframes
;
118 private CompressionLookupRecord
[] compressionLUTS
;
120 public UserDefinedImageSubheader
getUserDefinedImageSubheader()
122 return userDefSubheader
;
125 public RpfFrameFileComponents
getRpfFrameFileComponents()
127 return (null != userDefSubheader
) ? userDefSubheader
.getRpfFrameFileComponents() : null;
130 public NitfsImageSegment(java
.nio
.ByteBuffer buffer
, int headerStartOffset
, int headerLength
,int dataStartOffset
, int dataLength
)
132 super(NitfsSegmentType
.ImageSegment
, buffer
, headerStartOffset
, headerLength
, dataStartOffset
, dataLength
);
134 int saveOffset
= buffer
.position();
136 buffer
.position( headerStartOffset
);
137 // do not change order of parsing
138 this.parseIdentificationSecurityStructureFields(buffer
);
139 this.parseImageGeographicLocation(buffer
);
140 this.parseCommentRecords(buffer
);
141 this.parseImageCompressionStructure(buffer
);
142 this.parseImageBands(buffer
);
143 this.parseImageTableStructure(buffer
);
144 this.parseImageLocation(buffer
);
145 this.parseImageSubheaders(buffer
);
146 this.parseImageData(buffer
);
147 this.validateImage();
149 buffer
.position(saveOffset
); // last line - restore buffer's position
152 private void decompressBlock4x4(byte[][] block4x4
, short code
)
154 this.compressionLUTS
[0].copyValues(block4x4
[0], 0, code
, 4);
155 this.compressionLUTS
[1].copyValues(block4x4
[1], 0, code
, 4);
156 this.compressionLUTS
[2].copyValues(block4x4
[2], 0, code
, 4);
157 this.compressionLUTS
[3].copyValues(block4x4
[3], 0, code
, 4);
160 private void decompressBlock16(byte[] block16
, short code
)
162 this.compressionLUTS
[0].copyValues(block16
, 0, code
, 4);
163 this.compressionLUTS
[1].copyValues(block16
, 4, code
, 4);
164 this.compressionLUTS
[2].copyValues(block16
, 8, code
, 4);
165 this.compressionLUTS
[3].copyValues(block16
, 12, code
, 4);
169 public ByteBuffer
getImageAsDdsTexture() throws NitfsRuntimeException
171 RpfFrameFileComponents rpfComponents
= this.getRpfFrameFileComponents();
172 RpfLocationSection componentLocationTable
= rpfComponents
.componentLocationTable
;
174 int spatialDataSubsectionLocation
= componentLocationTable
.getSpatialDataSubsectionLocation();
175 super.buffer
.position( spatialDataSubsectionLocation
);
178 short[] codes
= new short[(int) this.numOfImageCodesPerRow
];
179 byte[] block16
= new byte[16];
180 int rowSize
= (int) ((this.numOfImageCodesPerRow
* this.imageCodeBitLength
) / 8L);
181 byte[] rowBytes
= new byte[rowSize
];
183 short subFrameIdx
= 0;
185 int band
= 0; // for(int band = 0; band < rpfComponents.numOfSpectralBandTables; band++)
186 NitfsImageBand imageBand
= this.imageBands
[band
];
188 Rpf2DdsCompress ddsCompress
= (1 == imageBand
.getNumOfLookupTables())
189 ?
new Cib2DdsCompress() : new Cadrg2DdsCompress();
191 boolean imageHasTransparentAreas
= ( this.hasTransparentPixels
|| this.hasMaskedSubframes
);
192 if( imageHasTransparentAreas
)
197 // Allocate space for the DDS texture
198 int bufferSize
= 128 + this.numSignificantCols
* this.numSignificantRows
/ 2;
199 java
.nio
.ByteBuffer ddsBuffer
= java
.nio
.ByteBuffer
.allocateDirect(bufferSize
);
200 ddsBuffer
.order(java
.nio
.ByteOrder
.LITTLE_ENDIAN
);
201 ddsCompress
.writeDxt1Header(ddsBuffer
, this.numSignificantCols
, this.numSignificantRows
);
202 int ddsHeaderLength
= ddsBuffer
.position();
205 for (int subFrameH
= 0; subFrameH
< this.numOfBlocksPerCol
; subFrameH
++)
207 for (int subFrameW
= 0; subFrameW
< this.numOfBlocksPerRow
; subFrameW
++, subFrameIdx
++ )
209 int blockY
= (int) (subFrameH
* rpfComponents
.numOfOutputRowsPerSubframe
);
210 int blockX
= (int) (subFrameW
* rpfComponents
.numOfOutputColumnsPerSubframe
);
212 if(hasMaskedSubframes
)
214 subFrameOffset
= this.subFrameOffsets
[subFrameIdx
];
215 if( -1 == subFrameOffset
)
216 { // this is a masked / transparent(?) subframe
217 DDSBlock4x4 ddsBlock
= ddsCompress
.getDxt1TransparentBlock4x4();
219 for (int row
= 0; row
< this.numOfImageRows
; row
++)
221 int qy
= blockY
+ row
* 4;
222 for (int col
= 0; col
< this.numOfImageCodesPerRow
; col
++)
224 int qx
= blockX
+ col
* 4;
225 ddsBuffer
.position(ddsHeaderLength
+ (qy
* this.numSignificantCols
) / 2 + 2 * qx
);
226 ddsBlock
.writeTo( ddsBuffer
);
227 } // end of column loop
233 super.buffer
.position( spatialDataSubsectionLocation
+ subFrameOffset
);
237 for (int row
= 0; row
< this.numOfImageRows
; row
++)
239 int qy
= blockY
+ row
* 4;
240 super.buffer
.get(rowBytes
, 0, rowSize
);
242 for (int i
= 0, cidx
= 0, bidx
= 0; i
< (int) this.numOfImageCodesPerRow
/ 2; i
++)
244 aa
= (short) ((0x00FF & (short) rowBytes
[bidx
++]) << 4);
245 ab
= (short) (0x00FF & (short) rowBytes
[bidx
++]);
246 bb
= (short) (0x00FF & (short) rowBytes
[bidx
++]);
248 codes
[cidx
++] = (short) (aa
| ((0x00F0 & ab
) >> 4));
249 codes
[cidx
++] = (short) (bb
| ((0x000F & ab
) << 8));
252 for (int col
= 0; col
< this.numOfImageCodesPerRow
; col
++)
254 int qx
= blockX
+ col
* 4;
255 this.decompressBlock16( block16
, codes
[col
] );
257 DDSBlock4x4 ddsBlock
= ddsCompress
.compressDxt1Block4x4( imageBand
, block16
, false );
259 ddsBuffer
.position( ddsHeaderLength
+ (qy
* this.numSignificantCols
)/2 + 2 * qx
);
260 ddsBlock
.writeTo( ddsBuffer
);
261 } // end of column loop
263 } // end of subFrameW loop
264 } // end of subFrameH loop
269 public IntBuffer
getImagePixelsAsArray(IntBuffer pixels
, RpfImageType imageType
) throws NitfsRuntimeException
271 RpfFrameFileComponents rpfComponents
= this.getRpfFrameFileComponents();
272 RpfLocationSection componentLocationTable
= rpfComponents
.componentLocationTable
;
274 int spatialDataSubsectionLocation
= componentLocationTable
.getSpatialDataSubsectionLocation();
275 super.buffer
.position( spatialDataSubsectionLocation
);
277 int band
= 0; // for(int band = 0; band < rpfComponents.numOfSpectralBandTables; band++)
278 NitfsImageBand imageBand
= this.imageBands
[band
];
280 int rgbColor
, colorCode
;
282 short[] codes
= new short[(int) this.numOfImageCodesPerRow
];
283 byte[][] block4x4
= new byte[4][4];
284 int rowSize
= (short) ((this.numOfImageCodesPerRow
* this.imageCodeBitLength
) / 8L);
285 byte[] rowBytes
= new byte[rowSize
];
287 short subFrameIdx
= 0;
289 for (int subFrameH
= 0; subFrameH
< this.numOfBlocksPerCol
; subFrameH
++)
291 for (int subFrameW
= 0; subFrameW
< this.numOfBlocksPerRow
; subFrameW
++, subFrameIdx
++ )
293 int blockY
= (int) (subFrameH
* rpfComponents
.numOfOutputRowsPerSubframe
);
294 int blockX
= (int) (subFrameW
* rpfComponents
.numOfOutputColumnsPerSubframe
);
296 if(hasMaskedSubframes
)
298 subFrameOffset
= this.subFrameOffsets
[subFrameIdx
];
299 if( -1 == subFrameOffset
)
300 { // this is a masked / transparent(?) subframe
305 super.buffer
.position( spatialDataSubsectionLocation
+ subFrameOffset
);
309 for (int row
= 0; row
< this.numOfImageRows
; row
++)
311 int qy
= blockY
+ row
* 4;
313 super.buffer
.get(rowBytes
, 0, rowSize
);
315 // short[] codes = new short[(int) this.numOfImageCodesPerRow];
316 for (int i
= 0, cidx
= 0, bidx
= 0; i
< (int) this.numOfImageCodesPerRow
/ 2; i
++)
318 aa
= (short) ((0x00FF & (short) rowBytes
[bidx
++]) << 4);
319 ab
= (short) (0x00FF & (short) rowBytes
[bidx
++]);
320 bb
= (short) (0x00FF & (short) rowBytes
[bidx
++]);
322 codes
[cidx
++] = (short) (aa
| ((0x00F0 & ab
) >> 4));
323 codes
[cidx
++] = (short) (bb
| ((0x000F & ab
) << 8));
326 for (int col
= 0; col
< this.numOfImageCodesPerRow
; col
++)
328 this.decompressBlock4x4( block4x4
, codes
[col
] );
330 int qx
= blockX
+ col
* 4;
332 for (int h
= 0; h
< 4; h
++)
334 for (int w
= 0; w
< 4; w
++)
336 colorCode
= 0x00FF & block4x4
[h
][w
];
337 rgbColor
= imageBand
.lookupRGB(colorCode
);
340 case IMAGE_TYPE_ALPHA_RGB
:
341 rgbColor
= 0xFF000000 + rgbColor
;
343 // case IMAGE_TYPE_GRAY:
345 // case IMAGE_TYPE_RGB:
347 case IMAGE_TYPE_GRAY_ALPHA
:
348 rgbColor
= (rgbColor
<< 8) + 0xFF;
350 case IMAGE_TYPE_RGB_ALPHA
:
351 rgbColor
= (rgbColor
<< 8) + 0xFF;
354 // pixels[(qy + h) * this.numSignificantCols + (qx + w)] = rgbColor;
355 pixels
.put((qy
+ h
) * this.numSignificantCols
+ (qx
+ w
), rgbColor
);
358 } // end of column loop
360 } // end of subFrameW loop
361 } // end of subFrameH loop
366 private void validateImage() throws NitfsRuntimeException
368 RpfFrameFileComponents rpfComponents
= this.getRpfFrameFileComponents();
370 if(1 != this.compressionAlgorithmID
)
371 throw new NitfsRuntimeException("NitfsReader.UnsupportedCompressionAlgorithm");
372 if( !StringUtil
.Equals( this.imageMode
, "B"))
373 throw new NitfsRuntimeException("NitfsReader.UnsupportedImageMode");
374 if( 1 != rpfComponents
.numOfSpectralGroups
)
375 throw new NitfsRuntimeException("NitfsReader.UnsupportedNumberOfSpectralGroups.");
376 if( 12 != this.imageCodeBitLength
)
377 throw new NitfsRuntimeException("NitfsReader.UnsupportedImageCodeBitLength.");
384 private void parseRpfMaskSubsection(java
.nio
.ByteBuffer buffer
) throws NitfsRuntimeException
386 // parse [ nitf-rpf mask subsection ]
387 this.subframeSequenceRecordLength
= NitfsUtil
.getUShort(buffer
);
388 this.transparencySequenceRecordLength
= NitfsUtil
.getUShort(buffer
);
389 this.transparentOutputPixelCodeLength
= NitfsUtil
.getUShort(buffer
);
391 if( 0 != this.transparentOutputPixelCodeLength
)
393 this.transparentOutputPixelCode
= new byte[(int)this.transparentOutputPixelCodeLength
];
394 buffer
.get(this.transparentOutputPixelCode
, 0, (int)this.transparentOutputPixelCodeLength
);
397 if(0 < this.subframeSequenceRecordLength
)
399 RpfFrameFileComponents rpfComponents
= this.getRpfFrameFileComponents();
400 subFrameOffsets
= new int[ this.numOfBlocksPerCol
* this.numOfBlocksPerRow
];
401 // parse [ nitf-rpf subframe mask table ]
403 for(int group
= 0 ; group
< rpfComponents
.numOfSpectralGroups
; group
++ )
405 for(int row
= 0 ; row
< this.numOfBlocksPerCol
; row
++ )
407 for(int col
= 0 ; col
< this.numOfBlocksPerRow
; col
++ )
408 subFrameOffsets
[idx
++] = (int) NitfsUtil
.getUInt(buffer
);
412 hasMaskedSubframes
= (null != this.subFrameOffsets
&& 0 < this.subFrameOffsets
.length
);
416 this.subFrameOffsets
= null;
418 this.hasMaskedSubframes
= (null != this.subFrameOffsets
&& 0 < this.subFrameOffsets
.length
);
419 this.hasTransparentPixels
= (0 < this.transparencySequenceRecordLength
);
423 private void parseImageData(java
.nio
.ByteBuffer buffer
) throws NitfsRuntimeException
425 RpfLocationSection componentLocationTable
= this.getRpfFrameFileComponents().componentLocationTable
;
427 buffer
.position(this.dataStartOffset
);
428 long spatialDataOffset
= NitfsUtil
.getUInt(buffer
);
430 if(0 < componentLocationTable
.getMaskSubsectionLength())
432 // parse nitf-rpf mask subsection
433 buffer
.position( componentLocationTable
.getMaskSubsectionLocation() );
434 this.parseRpfMaskSubsection(buffer
);
437 if(0 < componentLocationTable
.getImageDisplayParametersSubheaderLength())
438 { // parse [ nitf-rpf image display parameter sub-header ]
439 buffer
.position( componentLocationTable
.getImageDisplayParametersSubheaderLocation() );
440 this.parseImageDisplayParametersSubheader(buffer
);
443 throw new NitfsRuntimeException("NitfsReader.ImageDisplayParametersSubheaderNotFound");
445 // [ nitf rpf compression section ]
446 if(0 < componentLocationTable
.getCompressionSectionSubheaderLength())
447 { // parse [ nitf-rpf compression section sub-header ]
448 buffer
.position( componentLocationTable
.getCompressionSectionSubheaderLocation() );
449 this.parseRpfCompressionSectionSubheader(buffer
);
452 throw new NitfsRuntimeException("NitfsReader.RpfCompressionSectionSubheaderNotFound");
454 // [ nitf rpf compression lookup sub-section ]
455 if(0 < componentLocationTable
.getCompressionLookupSubsectionLength())
457 buffer
.position( componentLocationTable
.getCompressionLookupSubsectionLocation() );
458 this.parseRpfCompressionLookupSubsection(buffer
);
461 throw new NitfsRuntimeException("NitfsReader.RpfCompressionLookupSubsectionNotFound");
463 // [ nitf rpf compression parameter subsection ]
464 if(0 < componentLocationTable
.getCompressionParameterSubsectionLength())
465 throw new NitfsRuntimeException("NitfsReader.RpfCompressionParameterSubsectionNotImplemented");
467 // [ nitf rpf spatial data subsection ]
468 if(0 < componentLocationTable
.getSpatialDataSubsectionLength())
471 buffer
.position( componentLocationTable
.getSpatialDataSubsectionLocation() );
472 this.parseRpfSpatialDataSubsection(buffer
);
475 throw new NitfsRuntimeException("NitfsReader.RpfSpatialDataSubsectionNotFound");
478 private void parseRpfSpatialDataSubsection(java
.nio
.ByteBuffer buffer
) throws NitfsRuntimeException
484 private void parseRpfCompressionLookupSubsection(java
.nio
.ByteBuffer buffer
)
485 throws NitfsRuntimeException
487 int compressionLookupSubsectionLocation
= buffer
.position();
488 // [ nitf rpf compression lookup sub-section ]
489 this.compressionLookupOffsetTableOffset
= NitfsUtil
.getUInt(buffer
);
490 this.compressionLookupTableOffsetRecordLength
= NitfsUtil
.getUShort(buffer
);
492 this.compressionLUTS
= new CompressionLookupRecord
[this.numOfCompressionLookupOffsetRecords
];
493 for(int i
= 0 ; i
< this.numOfCompressionLookupOffsetRecords
; i
++)
495 this.compressionLUTS
[i
] = new CompressionLookupRecord( buffer
,
496 compressionLookupSubsectionLocation
,
497 this.getRpfFrameFileComponents().rpfColorMaps
);
501 private void parseRpfCompressionSectionSubheader(java
.nio
.ByteBuffer buffer
) throws NitfsRuntimeException
503 // parse [ nitf-rpf compression section sub-header ]
504 this.compressionAlgorithmID
= NitfsUtil
.getUShort(buffer
);
505 this.numOfCompressionLookupOffsetRecords
= NitfsUtil
.getUShort(buffer
);
506 this.numOfCompressionParameterOffsetRecords
= NitfsUtil
.getUShort(buffer
);
509 private void parseImageDisplayParametersSubheader(java
.nio
.ByteBuffer buffer
) throws NitfsRuntimeException
511 // parse [ nitf-rpf image display parameter sub-header ]
512 this.numOfImageRows
= NitfsUtil
.getUInt(buffer
);
513 this.numOfImageCodesPerRow
= NitfsUtil
.getUInt(buffer
);
514 this.imageCodeBitLength
= NitfsUtil
.getByteAsShort(buffer
);
517 private void parseImageSubheaders(java
.nio
.ByteBuffer buffer
) throws NitfsRuntimeException
519 this.userDefinedSubheaderLength
= NitfsUtil
.getShortNumeric(buffer
, 5);
520 if (0 == this.userDefinedSubheaderLength
)
522 this.userDefSubheader
= null;
526 this.userDefSubheader
= new UserDefinedImageSubheader(buffer
);
528 private void parseImageLocation(java
.nio
.ByteBuffer buffer
) throws NitfsRuntimeException
530 this.imageRowOffset
= NitfsUtil
.getShortNumeric(buffer
, 5);
531 this.imageColOffset
= NitfsUtil
.getShortNumeric(buffer
, 5);
532 // [ nitf image magnification ]
533 this.imageMagnification
= NitfsUtil
.getString(buffer
, 4);
536 private void parseImageTableStructure(java
.nio
.ByteBuffer buffer
) throws NitfsRuntimeException
538 this.imageSyncCode
= NitfsUtil
.getShortNumeric(buffer
, 1);
539 this.imageMode
= NitfsUtil
.getString(buffer
, 1);
540 this.numOfBlocksPerRow
= NitfsUtil
.getShortNumeric(buffer
, 4);
541 this.numOfBlocksPerCol
= NitfsUtil
.getShortNumeric(buffer
, 4);
542 this.numOfPixelsPerBlockH
= NitfsUtil
.getShortNumeric(buffer
, 4);
543 this.numOfPixelsPerBlockV
= NitfsUtil
.getShortNumeric(buffer
, 4);
544 this.numOfBitsPerPixelPerBand
= NitfsUtil
.getShortNumeric(buffer
, 2);
545 this.displayLevel
= NitfsUtil
.getShortNumeric(buffer
, 3);
546 this.attachmentLevel
= NitfsUtil
.getShortNumeric(buffer
, 3);
549 private void parseImageBands(java
.nio
.ByteBuffer buffer
) throws NitfsRuntimeException
552 throw new NitfsRuntimeException("NitfsReader.InvalidNumberOfImageBands");
553 this.imageBands
= new NitfsImageBand
[this.NBANDS
];
554 for(int i
= 0 ; i
< this.NBANDS
; i
++)
555 this.imageBands
[i
] = new NitfsImageBand(buffer
);
557 private void parseImageCompressionStructure(java
.nio
.ByteBuffer buffer
)
559 this.imageCompression
= NitfsUtil
.getString(buffer
, 2);
560 this.compressionRateCode
= NitfsUtil
.getString(buffer
, 4);
561 this.NBANDS
= NitfsUtil
.getShortNumeric(buffer
, 1);
564 private void parseCommentRecords(java
.nio
.ByteBuffer buffer
)
566 int numCommentRecords
= NitfsUtil
.getShortNumeric(buffer
, 1);
567 if(0 < numCommentRecords
)
569 this.imageCommentRecords
= new String
[numCommentRecords
];
570 for(int i
= 0; i
< numCommentRecords
; i
++)
571 this.imageCommentRecords
[i
] = NitfsUtil
.getString(buffer
, 80);
574 this.imageCommentRecords
= null;
577 private void parseImageGeographicLocation(java
.nio
.ByteBuffer buffer
)
580 double deg
, min
, sec
, lat
, lon
;
581 double sixty
= (double) 60.0;
582 this.imageCoords
= new LatLon
[4];
583 for (int i
= 0; i
< 4; i
++)
585 deg
= (double)NitfsUtil
.getShortNumeric(buffer
, 2);
586 min
= (double)NitfsUtil
.getShortNumeric(buffer
, 2);
587 sec
= (double)NitfsUtil
.getShortNumeric(buffer
, 2);
588 hemisphere
= NitfsUtil
.getString(buffer
, 1);
589 lat
= deg
+ (min
+ (sec
/ sixty
)) / sixty
; // deciaml latitude
590 if(StringUtil
.Equals(hemisphere
, "N"))
593 deg
= (double)NitfsUtil
.getShortNumeric(buffer
, 3);
594 min
= (double)NitfsUtil
.getShortNumeric(buffer
, 2);
595 sec
= (double)NitfsUtil
.getShortNumeric(buffer
, 2);
596 hemisphere
= NitfsUtil
.getString(buffer
, 1);
597 lon
= deg
+ (min
+ (sec
/ sixty
)) / sixty
; // deciaml longitude
598 if(StringUtil
.Equals(hemisphere
, "W"))
601 // TODO Do not waste time on this calculations - the same info is repeated in the [ rpf coverage section ]
602 // TODO zz: garakl: convert to LatLon according to the CoordinateSystem
603 // if(0 == StringUtil.compare(imageCoordSystem, "G"))
604 this.imageCoords
[i
] = LatLon
.fromDegrees(lat
, lon
);
608 private void parseIdentificationSecurityStructureFields(java
.nio
.ByteBuffer buffer
)
609 throws NitfsRuntimeException
611 // [ nitf identification , security, structure fields]
612 this.partType
= NitfsUtil
.getString(buffer
, 2);
613 if(!StringUtil
.Equals("IM", this.partType
))
614 throw new NitfsRuntimeException("NitfsReader.UnexpectedSegmentType", this.partType
);
616 this.imageID
= NitfsUtil
.getString(buffer
, 10);
617 boolean isSupportedFormat
= false;
618 for(String s
: SupportedFormats
)
620 if(0 == s
.compareTo(this.imageID
))
622 isSupportedFormat
= true;
626 if(!isSupportedFormat
)
627 throw new NitfsRuntimeException("NitfsReader.UnsupportedImageFormat", this.imageID
);
629 this.dateTime
= NitfsUtil
.getString(buffer
, 14);
630 this.targetID
= NitfsUtil
.getString(buffer
, 17);
631 this.imageTitle
= NitfsUtil
.getString(buffer
, 80);
632 this.securityClass
= NitfsUtil
.getString(buffer
, 1);
633 this.codewords
= NitfsUtil
.getString(buffer
, 40);
634 this.controlAndHandling
= NitfsUtil
.getString(buffer
, 40);
635 this.releaseInstructions
= NitfsUtil
.getString(buffer
, 40);
636 this.classAuthority
= NitfsUtil
.getString(buffer
, 20); // ISCAUT
637 this.securityCtrlNum
= NitfsUtil
.getString(buffer
, 20); // ISCTLN
638 this.ISDWNG
= NitfsUtil
.getString(buffer
, 6);
639 this.ISDEVT
= StringUtil
.Equals(this.ISDWNG
, "999998") ? NitfsUtil
.getString(buffer
, 40) : StringUtil
.EMPTY
;
641 this.encryption
= NitfsUtil
.getShortNumeric(buffer
, 1);
642 this.imageSource
= NitfsUtil
.getString(buffer
, 42);
643 this.numSignificantRows
= NitfsUtil
.getNumeric(buffer
, 8);
644 this.numSignificantCols
= NitfsUtil
.getNumeric(buffer
, 8);
645 this.pixelValueType
= NitfsUtil
.getString(buffer
, 3);
646 this.imageRepresentation
= NitfsUtil
.getString(buffer
, 8);
647 this.imageCategory
= NitfsUtil
.getString(buffer
, 8);
648 this.bitsPerPixelPerBand
= NitfsUtil
.getShortNumeric(buffer
, 2);
649 this.pixelJustification
= NitfsUtil
.getString(buffer
, 1);
650 this.imageCoordSystem
= NitfsUtil
.getString(buffer
, 1);