Worldwind public release 0.2.1
[worldwind-tracker.git] / gov / nasa / worldwind / formats / nitfs / NitfsImageSegment.java
blob66cff1d1529697618a147190d63a4e4cdd34bd98
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.*;
7 import java.nio.*;
8 /*
9 Copyright (C) 2001, 2007 United States Government
10 as represented by the Administrator of the
11 National Aeronautics and Space Administration.
12 All Rights Reserved.
15 /**
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;
48 // [ nitf comments ]
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 );
177 short aa, ab, bb;
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];
182 int subFrameOffset;
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
229 continue;
231 else
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
262 } // end of row loop
263 } // end of subFrameW loop
264 } // end of subFrameH loop
266 return ddsBuffer;
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;
281 short aa, ab, bb;
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];
286 int subFrameOffset;
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
301 continue;
303 else
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);
338 switch (imageType)
340 case IMAGE_TYPE_ALPHA_RGB:
341 rgbColor = 0xFF000000 + rgbColor;
342 break;
343 // case IMAGE_TYPE_GRAY:
344 // break;
345 // case IMAGE_TYPE_RGB:
346 // break;
347 case IMAGE_TYPE_GRAY_ALPHA:
348 rgbColor = (rgbColor << 8) + 0xFF;
349 break;
350 case IMAGE_TYPE_RGB_ALPHA:
351 rgbColor = (rgbColor << 8) + 0xFF;
352 break;
354 // pixels[(qy + h) * this.numSignificantCols + (qx + w)] = rgbColor;
355 pixels.put((qy + h) * this.numSignificantCols + (qx + w), rgbColor);
358 } // end of column loop
359 } // end of row loop
360 } // end of subFrameW loop
361 } // end of subFrameH loop
363 return pixels;
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 ]
402 int idx = 0;
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);
414 else
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);
442 else
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);
451 else
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);
460 else
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);
474 else
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;
523 return;
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
551 if(0 == this.NBANDS)
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);
573 else
574 this.imageCommentRecords = null;
577 private void parseImageGeographicLocation(java.nio.ByteBuffer buffer)
579 String hemisphere;
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"))
591 lat *= (double)-1.0;
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"))
599 lon *= (double)-1.0;
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;
623 break;
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);