OSSIM - Open Source Software Image Map  Version 1.9.0 (20180803)
ossimJ2kTlmRecord.cpp
Go to the documentation of this file.
1 //---
2 //
3 // License: MIT
4 //
5 // Author: David Burken
6 //
7 // Description: Container class definition for J2K Tile-part lengths record.
8 // See document BPJ2K01.10 Table 7-21 for detailed description.
9 //
10 // $Id$
11 //---
12 
15 #include <ossim/base/ossimCommon.h>
16 #include <ossim/base/ossimEndian.h>
18 #include <ossim/base/ossimNotify.h>
19 #include <iostream>
20 #include <iomanip>
21 #include <cstring>
22 
23 
25  :
26  m_Ltlm(0),
27  m_Ztlm(0),
28  m_Stlm(0x40), // Tiles in order 32 bit Ptlm
29  m_Ttlm(0),
30  m_Ptlm(0)
31 {
32 }
33 
35 {
36  clear();
37 }
38 
40 {
41  clearTtlm();
42  clearPtlm();
43 }
44 
46 {
47  if ( m_Ttlm )
48  {
49  ossim_uint8 st = getSt();
50  if ( st == 1 )
51  {
53  delete [] p;
54  }
55  else if ( st == 2 )
56  {
58  delete [] p;
59  }
60  m_Ttlm = 0;
61  }
62 }
63 
65 {
66  if ( m_Ptlm )
67  {
68  ossim_uint8 sp = getSp();
69  if ( sp == 0 )
70  {
72  delete [] p;
73  }
74  else if ( sp == 1 )
75  {
77  delete [] p;
78  }
79  m_Ptlm = 0;
80  }
81 }
82 
84 {
85  clear(); // Deletes m_Ttlm and m_Ptlm arrays if they exist.
86 
87  ossimEndian* endian = 0;
89  {
90  // Stored big endian, must swap.
91  endian = new ossimEndian();
92  }
93 
94  // Get the stream posistion.
95  std::streamoff pos = in.tellg();
96 
97  // Note: Marker is not read.
98 
99  // Length of segment minus marker.
100  in.read((char*)&m_Ltlm, 2);
101  if ( endian )
102  {
103  endian->swap(m_Ltlm);
104  }
105 
106  // Index of marker segment relative to all other TLM marker segments.
107  in.read((char*)&m_Ztlm, 1);
108 
109  // Stlm contains two variables in one byte, ST and SP.
110  in.read((char*)&m_Stlm, 1);
111 
112  ossim_uint16 tile_count = getTileCount();
113  if ( tile_count )
114  {
115  ossim_uint8 st = getSt();
116 
117  //---
118  // Get the Ttlm array if any:
119  // st value of 0 means tiles are in order and no Ttlm array.
120  //---
121  if ( st == 1 ) // 8 bit
122  {
123  ossim_uint8* p = new ossim_uint8[tile_count];
124  in.read((char*)p, tile_count);
125  m_Ttlm = p;
126  }
127  else if ( st == 2 ) // 16 bit
128  {
129  ossim_uint16* p = new ossim_uint16[tile_count];
130  in.read((char*)p, tile_count*2);
131  if ( endian )
132  {
133  endian->swap(p, tile_count);
134  }
135  m_Ttlm = p;
136  }
137  else if ( st > 2 )
138  {
140  << "ossimJ2kTlmRecord::parseStream(...) Bad tlm ST value!"
141  << std::endl;
142  }
143 
144  // Get the Ptlm array:
145  ossim_uint8 sp = getSp();
146  if ( sp == 0 ) // 16 bit
147  {
148  ossim_uint16* p = new ossim_uint16[tile_count];
149  in.read((char*)p, tile_count*2);
150  if ( endian )
151  {
152  endian->swap(p, tile_count);
153  }
154  m_Ptlm = p;
155  }
156  else if ( sp == 1 ) // 32 bit
157  {
158  ossim_uint32* p = new ossim_uint32[tile_count];
159  in.read((char*)p, tile_count*4);
160  if ( endian )
161  {
162  endian->swap(p, tile_count);
163  }
164  m_Ptlm = p;
165  }
166  else
167  {
169  << "ossimJ2kTlmRecord::parseStream(...) Bad tlm SP value!"
170  << std::endl;
171  }
172  }
173 
174  // Clean up::
175  if ( endian )
176  {
177  delete endian;
178  endian = 0;
179  }
180 
181  //---
182  // Seek to next record in case there was a parse error and we didn't read
183  // all bytes.
184  //---
185  in.seekg(pos + m_Ltlm, std::ios_base::beg);
186 }
187 
189 {
190  ossim_uint16 tileCount = getTileCount();
191  ossim_uint8 st = getSt();
192  ossim_uint8 sp = getSp();
193 
194  ossimEndian* endian = 0;
196  {
197  // Stored in file big endian, must swap.
198  endian = new ossimEndian();
199  endian->swap( m_Ltlm );
200 
201  // Conditional ttlm array:
202  if ( st == 2 )
203  {
204  endian->swap( (ossim_uint16*)m_Ttlm, tileCount );
205  }
206 
207  // Conditional ptlm array:
208  if (sp == 0 )
209  {
210  endian->swap( (ossim_uint16*)m_Ptlm, tileCount );
211  }
212  else if ( sp == 1 )
213  {
214  endian->swap( (ossim_uint32*)m_Ptlm, tileCount );
215  }
216  }
217 
218  // Marker 0xff55:
219  out.put( 0xff );
220  out.put( 0x55 );
221 
222  out.write( (char*)&m_Ltlm, 2);
223  out.write( (char*)&m_Ztlm, 1);
224  out.write( (char*)&m_Stlm, 1);
225 
226  // Conditional array of tile indexes:
227  if ( st == 1 ) // 8 bit array
228  {
229  out.write( (char*)m_Ttlm, tileCount );
230  }
231  else if ( st == 2 ) // 16 bit array
232  {
233  out.write( (char*)m_Ttlm, tileCount*2 );
234  }
235 
236  // Conditional array of tile byte counts:
237  if ( sp == 0 ) // 16 bit array
238  {
239  out.write( (char*)m_Ptlm, tileCount*2 );
240  }
241  else if ( sp == 1 ) // 32 bit array
242  {
243  out.write( (char*)m_Ptlm, tileCount*4 );
244  }
245 
246  if ( endian )
247  {
248  // Swap back to native:
249  endian->swap( m_Ltlm );
250 
251  // Conditional ttlm array:
252  if ( st == 2 )
253  {
254  endian->swap( (ossim_uint16*)m_Ttlm, tileCount );
255  }
256 
257  // Conditional ptlm array:
258  if (sp == 0 )
259  {
260  endian->swap( (ossim_uint16*)m_Ptlm, tileCount );
261  }
262  else if ( sp == 1 )
263  {
264  endian->swap( (ossim_uint32*)m_Ptlm, tileCount );
265  }
266 
267  // Cleanup:
268  delete endian;
269  endian = 0;
270  }
271 }
272 
274 {
275  // 5th and 6th bits.
276  return (m_Stlm & 0x30) >> 4;
277 }
278 
280 {
281  bool result = true;
282 
283  // 5th and 6th bits
284  if ( bits == 0 )
285  {
286  // Clear both 5th and 6th bit.
287  m_Stlm = m_Stlm & 0xcf;
288  }
289  else if ( bits == 1 )
290  {
291  // Set the 5th bit clear the 6th bit.
292  m_Stlm = (m_Stlm & 0xdf) | 0x10;
293  }
294  else if ( bits == 2 )
295  {
296  // Set the 6th bit, clear the 5th bit.
297  m_Stlm = (m_Stlm & 0xef) | 0x20;
298  }
299  else
300  {
301  result = false;
302  }
303 
304  return result;
305 }
306 
308 {
309  return m_Ztlm;
310 }
311 
313 {
314  // Last two bits.
315  return m_Stlm >> 6;
316 }
317 
319 {
320  bool result = true;
321 
322  // 7th bit
323  if ( bit == 0 )
324  {
325  // Clear the 7th bit:
326  m_Stlm = m_Stlm & 0xbf;
327  }
328  else if ( bit == 1 )
329  {
330  // Set the 7th bit.
331  m_Stlm = m_Stlm | 0x40;
332  }
333  else
334  {
335  result = false;
336  }
337  return result;
338 }
339 
341 {
342  bool result = setSp( spBit );
343 
344  clearPtlm();
345 
346  if ( spBit == 0 )
347  {
348  m_Ptlm = new ossim_uint16[count];
349  std::memset( m_Ptlm, 0, count*2 );
350  }
351  else if ( spBit == 1 )
352  {
353  m_Ptlm = new ossim_uint32[count];
354  std::memset( m_Ptlm, 0, count*4 );
355  }
356 
357  m_Ltlm = computeLength( count );
358 
359  return result;
360 }
361 
363 {
364  // See Table 7-21 BPJ2K01.10:
365  ossim_uint16 result = 0;
366  if ( m_Ltlm )
367  {
368  ossim_uint8 st = getSt();
369  ossim_uint8 sp = getSp();
370  ossim_uint16 x = st + (sp==0?2:4);
371  if ( x )
372  {
373  result = (m_Ltlm - 4) / x;
374  }
375  }
376  return result;
377 }
378 
380 {
381  bool status = false;
382  if ( (index >= 0) && ( index < getTileCount() ) )
383  {
384  ossim_uint8 sp = getSp();
385  if ( sp == 0 )
386  {
388  length = p[index];
389  status = true;
390  }
391  else if ( sp == 1 )
392  {
394  length = p[index];
395  status = true;
396  }
397  }
398 
399  return status;
400 }
401 
403  ossim_int32 index, ossim_uint32 length )
404 {
405  bool status = false;
406  if ( (index >= 0) && ( index < getTileCount() ) )
407  {
408  ossim_uint8 sp = getSp();
409  if ( sp == 0 )
410  {
412  p[index] = static_cast<ossim_uint16>(length);
413  status = true;
414  }
415  else if ( sp == 1 )
416  {
418  p[index] = length;
419  status = true;
420  }
421  }
422 
423  return status;
424 }
425 
427  ossim_int32 first, ossim_int32 last, std::streampos& init ) const
428 {
429  bool status = false;
430  if ( (first >= 0) && (last>first) && (last <= getTileCount()) )
431  {
432  ossim_uint8 sp = getSp();
433  if ( sp == 0 )
434  {
436  for ( ossim_int32 i = first; i < last; ++i )
437  {
438  init += p[i];
439  status = true;
440  }
441  }
442  else if ( sp == 1 )
443  {
445  for ( ossim_int32 i = first; i < last; ++i )
446  {
447  init += p[i];
448  status = true;
449  }
450  }
451  }
452  return status;
453 }
454 
456 {
457  return 4 + ( getSt() + (getSp()==1?4:2) ) * tileCount;
458 }
459 
461  const std::string& prefix) const
462 {
463  // Capture the original flags.
464  std::ios_base::fmtflags f = out.flags();
465 
466  std::string pfx = prefix;
467  pfx += "tlm.";
468 
469  out << pfx << "marker: 0xff55\n"
470  << pfx << "Ltlm: " << m_Ltlm << "\n"
471  << pfx << "Ztlm: " << int(m_Ztlm) << "\n";
472 
473  out.setf(std::ios_base::hex, std::ios_base::basefield);
474  out << pfx << "Stlm: 0x" << int(m_Stlm) << "\n";
475  out.setf(std::ios_base::fmtflags(0), std::ios_base::basefield);
476  out << pfx << "Stlm.ST: " << int(getSt()) << "\n"
477  << pfx << "Stlm.SP: " << int(getSp()) << "\n";
478 
479  ossim_uint16 tile_count = getTileCount();
480  if ( tile_count )
481  {
482  ossim_uint8 st = getSt();
483  if ( m_Ttlm == 0 )
484  {
485  out << pfx << "Ttlm: null\n";
486  }
487  else if ( st == 1 ) // 8 bit
488  {
490  for ( ossim_uint16 i = 0; i < tile_count; ++i )
491  {
492  out << pfx << "Ttlm[" << i << "]: " << (int)p[i] << "\n";
493  }
494  }
495  else if ( st == 2 ) // 16 bit
496  {
498  for ( ossim_uint16 i = 0; i < tile_count; ++i )
499  {
500  out << pfx << "Ttlm[" << i << "]: " << p[i] << "\n";
501  }
502  }
503 
504  ossim_uint8 sp = getSp();
505  if ( sp == 0 ) // 16 bit
506  {
508  for ( ossim_uint16 i = 0; i < tile_count; ++i )
509  {
510  out << pfx << "Ptlm[" << i << "]: " << p[i] << "\n";
511  }
512  }
513  else if ( sp == 1 ) // 32 bit
514  {
516  for ( ossim_uint16 i = 0; i < tile_count; ++i )
517  {
518  out << pfx << "Ptlm[" << i << "]: " << p[i] << "\n";
519  }
520  }
521  }
522 
523  out.flush();
524 
525  // Reset flags.
526  out.setf(f);
527 
528  return out;
529 }
530 
532 {
533  return obj.print(out);
534 }
535 
536 
ossim_uint8 m_Stlm
Indicator for Ttlm and Ptlm field sizes.
ossim_uint32 x
ossim_uint8 getSt() const
Get the ST portion of STLM field( bits 5 and 6).
~ossimJ2kTlmRecord()
destructor
void * m_Ptlm
The length, in bytes, from the beginning of the SOT marker of the tile-part to the end of the codestr...
std::ostream & print(std::ostream &out, const std::string &prefix=std::string()) const
print method that outputs a key/value type format adding prefix to keys.
OSSIM_DLL ossimByteOrder byteOrder()
Definition: ossimCommon.cpp:54
std::ostream & operator<<(std::ostream &out, const ossimJ2kTlmRecord &obj)
unsigned short ossim_uint16
void clearPtlm()
Deletes m_Ptlm array.
bool setTileLength(ossim_int32 index, ossim_uint32 length)
Sets the tile length for tile at x,y in ptlm array.
void writeStream(std::ostream &out)
Write method.
bool setSt(ossim_uint8 bits)
Set the ST bits of STLM field.
ossim_uint16 m_Ltlm
NOTE: tml segmet marker 0xff55 not stored.
void clearTtlm()
Deletes m_Ttlm array.
void clear()
Deletes m_Ttlm and m_Ptlm arrays.
ossim_uint16 computeLength(ossim_uint16 tileCount) const
Computes length of this segment minus marker itself.
ossim_uint8 getSp() const
void * m_Ttlm
Tile index for tile-parts.
void parseStream(ossim::istream &in)
Parse method.
ossim_uint16 getTileCount() const
unsigned int ossim_uint32
bool accumulate(ossim_int32 first, ossim_int32 last, std::streampos &init) const
Adds Ptlm array from first to last.
bool initPtlmArray(ossim_uint8 spBit, ossim_uint16 count)
Sets SP bit, initializes ptlm array, and ltlm(size).
return status
bool getTileLength(ossim_int32 index, ossim_uint32 &length) const
Get the tile length for tile at index from ptlm array.
std::basic_istream< char > istream
Base class for char input streams.
Definition: ossimIosFwd.h:20
ossim_uint8 m_Ztlm
Index of marker segment relative to all other TLM marker segments present in the current header...
ossim_uint8 getZtlm() const
bool setSp(ossim_uint8 bit)
Set the SP bit of Stlm field.
ossimJ2kTlmRecord()
default constructor
void swap(ossim_sint8 &)
Definition: ossimEndian.h:26
unsigned char ossim_uint8
OSSIMDLLEXPORT std::ostream & ossimNotify(ossimNotifyLevel level=ossimNotifyLevel_WARN)
std::basic_ostream< char > ostream
Base class for char output streams.
Definition: ossimIosFwd.h:23
int ossim_int32