1 /******************************************************************************
2 * $Id: nitfaridpcm.cpp 27745 2014-09-27 16:38:57Z goatbar $
3 *
4 * Project: NITF Read/Write Library
5 * Purpose: ARIDPCM reading code.
6 * Author: Frank Warmerdam, warmerdam@pobox.com
7 *
8 **********************************************************************
9 * Copyright (c) 2007, Frank Warmerdam
10 * Copyright (c) 2009, Even Rouault <even dot rouault at mines-paris dot org>
11 *
12 * Permission is hereby granted, free of charge, to any person obtaining a
13 * copy of this software and associated documentation files (the "Software"),
14 * to deal in the Software without restriction, including without limitation
15 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
16 * and/or sell copies of the Software, and to permit persons to whom the
17 * Software is furnished to do so, subject to the following conditions:
18 *
19 * The above copyright notice and this permission notice shall be included
20 * in all copies or substantial portions of the Software.
21 *
22 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
23 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
25 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
27 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
28 * DEALINGS IN THE SOFTWARE.
29 ****************************************************************************/
30
31 #include "gdal.h"
32 #include "nitflib.h"
33 #include "cpl_conv.h"
34
35 CPL_CVSID("$Id: nitfaridpcm.cpp 27745 2014-09-27 16:38:57Z goatbar $");
36
37 static const int neighbourhood_size_75[4] = { 23, 47, 74, 173 };
38 static const int bits_per_level_by_busycode_75[4/*busy code*/][4/*level*/] = {
39 { 8, 5, 0, 0 }, // BC = 00
40 { 8, 5, 2, 0 }, // BC = 01
41 { 8, 6, 4, 0 }, // BC = 10
42 { 8, 7, 4, 2 }};// BC = 11
43
44 #define CR075 1
45
46 // Level for each index value.
47 static const int level_index_table[64] =
48 { 0,
49 1, 1, 1,
50 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
51 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
52 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
53 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 };
54
55 // List of i,j to linear index macros mappings.
56 // Note that i is vertical and j is horizontal and progression is
57 // right to left, bottom to top.
58
59 #define IND(i,j) (ij_index[i+j*8]-1)
60
61 static const int ij_index[64] = {
62
63 1, // 0, 0
64 18, // 1, 0
65 6, // 2, 0
66 30, // 3, 0
67 3, // 4, 0
68 42, // 5, 0
69 12, // 6, 0
70 54, // 7, 0
71
72 17, // 0, 1
73 19, // 1, 1
74 29, // 2, 1
75 31, // 3, 1
76 41, // 4, 1
77 43, // 5, 1
78 53, // 6, 1
79 55, // 7, 1
80
81 5, // 0, 2
82 21, // 1, 2
83 7, // 2, 2
84 33, // 3, 2
85 11, // 4, 2
86 45, // 5, 2
87 13, // 6, 2
88 57, // 7, 2
89
90 20, // 0, 3
91 22, // 1, 3
92 32, // 2, 3
93 34, // 3, 3
94 44, // 4, 3
95 46, // 5, 3
96 56, // 6, 3
97 58, // 7, 3
98
99 2, // 0, 4
100 24, // 1, 4
101 9, // 2, 4
102 36, // 3, 4
103 4, // 4, 4
104 48, // 5, 4
105 15, // 6, 4
106 60, // 7, 4
107
108 23, // 0, 5
109 25, // 1, 5
110 35, // 2, 5
111 37, // 3, 5
112 47, // 4, 5
113 49, // 5, 5
114 59, // 6, 5
115 61, // 7, 5
116
117 8, // 0, 6
118 27, // 1, 6
119 10, // 2, 6
120 39, // 3, 6
121 14, // 4, 6
122 51, // 5, 6
123 16, // 6, 6
124 63, // 7, 6
125
126 26, // 0, 7
127 28, // 1, 7
128 38, // 2, 7
129 40, // 3, 7
130 50, // 4, 7
131 52, // 5, 7
132 62, // 6, 7
133 64};// 7, 7
134
135 static const int delta_075_level_2_bc_0[32] =
136 {-71, -49, -38, -32, -27, -23, -20, -17, -14, -12, -10, -8, -6, -4, -3, -1,
137 1, 2, 4, 6, 8, 12, 14, 16, 19, 22, 26, 31, 37, 46, 72 };
138 static const int delta_075_level_2_bc_1[32] =
139 {-71, -49, -38, -32, -27, -23, -20, -17, -14, -12, -10, -8, -6, -4, -3, -1,
140 1, 2, 4, 6, 8, 12, 14, 16, 19, 22, 26, 31, 37, 46, 72 };
141 static const int delta_075_level_2_bc_2[64] =
142 { -109, -82, -68, -59, -52, -46, -41, -37, -33, -30, -27, -25, -22, -20,
143 -18, -16, -15, -13, -11, -10, -9, -8, -7, -6, -5,
144 -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,
145 13,14,15,16,17,18,19,20,21,24,26,28,31,35,38,
146 42,47,52,60,69,85,118};
147 static const int delta_075_level_2_bc_3[128] =
148 {-159,-134,-122,-113,-106,-100,-94,-88,-83,-79,-76,-72,-69,-66,-63,-61,
149 -58,-56,-54,-52,-50,-48,-47,-45,-43,-42,-40,-39,-37,-36,-35,-33,-32,-31,
150 -30,-29,-28,-27,-25,-24,-23,-22,-21,-20,-19,-18,-17,-16,-15,-14,
151 -13,-12,-11,-10,-9,-8,-7,-6,-5,-4,-3,-2,-1,0,1,2,3,4,5,6,7,8,9,10,11,
152 12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,
153 35,36,37,38,39,40,41,42,43,45,48,52,56,60,64,68,73,79,85,92,100,109,
154 118,130,144,159,177,196,217,236};
155 static const int *delta_075_level_2[4] =
156 { delta_075_level_2_bc_0, delta_075_level_2_bc_1,
157 delta_075_level_2_bc_2, delta_075_level_2_bc_3 };
158
159
160 static const int delta_075_level_3_bc_1[4] = { -24, -6, 6, 24 };
161 static const int delta_075_level_3_bc_2[16] =
162 {-68,-37,-23,-15, -9, -6, -3, -1, 1, 4, 7,10,16,24,37,70 };
163 static const int delta_075_level_3_bc_3[16] =
164 {-117,-72, -50, -36, -25, -17, -10, -5,-1, 3, 7,14,25,45,82,166};
165 static const int *delta_075_level_3[4] =
166 { NULL, delta_075_level_3_bc_1,
167 delta_075_level_3_bc_2, delta_075_level_3_bc_3 };
168
169 static const int delta_075_level_4_bc_3[4] = {-47,-8,4,43};
170 static const int *delta_075_level_4[4] = { NULL, NULL, NULL, delta_075_level_4_bc_3 };
171
172 static const int **delta_075_by_level_by_bc[4] =
173 { NULL, delta_075_level_2, delta_075_level_3, delta_075_level_4 };
174
175 /************************************************************************/
176 /* get_bits() */
177 /************************************************************************/
178
179 static int
get_bits(unsigned char * buffer,int first_bit,int num_bits)180 get_bits( unsigned char *buffer, int first_bit, int num_bits )
181
182 {
183 int i;
184 int total =0;
185
186 for( i = first_bit; i < first_bit+num_bits; i++ )
187 {
188 total = total * 2;
189 if( buffer[i>>3] & (0x80 >> (i&7)) )
190 total++;
191 }
192
193 return total;
194 }
195
196 /************************************************************************/
197 /* get_delta() */
198 /* */
199 /* Compute the delta value for a particular (i,j) location. */
200 /************************************************************************/
201 static int
get_delta(unsigned char * srcdata,int nInputBytes,int busy_code,CPL_UNUSED int comrat,int block_offset,CPL_UNUSED int block_size,int i,int j,int * pbError)202 get_delta( unsigned char *srcdata,
203 int nInputBytes,
204 int busy_code,
205 CPL_UNUSED int comrat,
206 int block_offset,
207 CPL_UNUSED int block_size,
208 int i,
209 int j,
210 int *pbError )
211
212 {
213 CPLAssert( comrat == CR075 );
214 int pixel_index = IND(i,j);
215 int level_index = level_index_table[pixel_index];
216 const int *bits_per_level = bits_per_level_by_busycode_75[busy_code];
217 int delta_bits = bits_per_level[level_index];
218 int delta_offset = 0;
219
220 *pbError = FALSE;
221
222 if( delta_bits == 0 )
223 return 0;
224
225 if( level_index == 3 )
226 delta_offset = bits_per_level[0] + bits_per_level[1] * 3
227 + bits_per_level[2] * 12 + (pixel_index - 16) * bits_per_level[3];
228 else if( level_index == 2 )
229 delta_offset = bits_per_level[0] + bits_per_level[1] * 3
230 + (pixel_index - 4) * bits_per_level[2];
231 else if( level_index == 1 )
232 delta_offset = bits_per_level[0] + (pixel_index-1)*bits_per_level[1];
233
234 if (nInputBytes * 8 < block_offset+delta_offset + delta_bits)
235 {
236 CPLError( CE_Failure, CPLE_AppDefined, "Input buffer too small");
237 *pbError = TRUE;
238 return 0;
239 }
240
241 int delta_raw = get_bits( srcdata, block_offset+delta_offset, delta_bits );
242 int delta = delta_raw;
243
244 /* Should not happen as delta_075_by_level_by_bc[level_index] == NULL if and
245 only if level_index == 0, which means that pixel_index == 0, which means
246 (i, j) = (0, 0). That cannot happen as we are never called with those
247 values
248 */
249 CPLAssert( delta_075_by_level_by_bc[level_index] != NULL );
250 const int *lookup_table = delta_075_by_level_by_bc[level_index][busy_code];
251
252 CPLAssert( lookup_table != NULL );
253 delta = lookup_table[delta_raw];
254
255 return delta;
256 }
257
258 /************************************************************************/
259 /* decode_block() */
260 /* */
261 /* Decode one 8x8 block. The 9x9 L buffer is pre-loaded with */
262 /* the left and top values from previous blocks. */
263 /************************************************************************/
264 static int
decode_block(unsigned char * srcdata,int nInputBytes,int busy_code,int comrat,int block_offset,int block_size,int left_side,int top_side,int L[9][9])265 decode_block( unsigned char *srcdata, int nInputBytes,
266 int busy_code, int comrat,
267 int block_offset, int block_size,
268 int left_side, int top_side, int L[9][9] )
269
270 {
271 int i, j;
272 int bError;
273
274 // Level 2
275 L[0][4] = (L[0][0] + L[0][8])/2
276 + get_delta(srcdata,nInputBytes,busy_code,comrat,block_offset,block_size,0,4,&bError);
277 if (bError) return FALSE;
278 L[4][0] = (L[0][0] + L[8][0])/2
279 + get_delta(srcdata,nInputBytes,busy_code,comrat,block_offset,block_size,4,0,&bError);
280 if (bError) return FALSE;
281 L[4][4] = (L[0][0] + L[8][0] + L[0][8] + L[8][8])/4
282 + get_delta(srcdata,nInputBytes,busy_code,comrat,block_offset,block_size,4,4,&bError);
283 if (bError) return FALSE;
284
285 if( left_side )
286 L[4][8] = L[4][0];
287 if( top_side )
288 L[8][4] = L[0][4];
289
290 // Level 3
291 for( i = 0; i < 8; i += 4 )
292 {
293 for( j = 0; j < 8; j += 4 )
294 {
295 // above
296 L[i+2][j] = (L[i][j]+L[i+4][j])/2
297 + get_delta(srcdata,nInputBytes,busy_code,comrat,
298 block_offset,block_size,i+2,j,&bError);
299 if (bError) return FALSE;
300 // left
301 L[i][j+2] = (L[i][j]+L[i][j+4])/2
302 + get_delta(srcdata,nInputBytes,busy_code,comrat,
303 block_offset,block_size,i,j+2,&bError);
304 if (bError) return FALSE;
305 // up-left
306 L[i+2][j+2] = (L[i][j]+L[i][j+4]+L[i+4][j]+L[i+4][j+4])/4
307 + get_delta(srcdata,nInputBytes,busy_code,comrat,
308 block_offset,block_size,i+2,j+2,&bError);
309 if (bError) return FALSE;
310 }
311 }
312
313 if( left_side )
314 {
315 L[2][8] = L[2][0];
316 L[6][8] = L[6][0];
317 }
318 if( top_side )
319 {
320 L[8][2] = L[0][2];
321 L[8][6] = L[0][6];
322 }
323
324 // Level 4
325 for( i = 0; i < 8; i += 2 )
326 {
327 for( j = 0; j < 8; j += 2 )
328 {
329 // above
330 L[i+1][j] = (L[i][j]+L[i+2][j])/2
331 + get_delta(srcdata,nInputBytes,busy_code,comrat,
332 block_offset,block_size,i+1,j,&bError);
333 if (bError) return FALSE;
334 // left
335 L[i][j+1] = (L[i][j]+L[i][j+2])/2
336 + get_delta(srcdata,nInputBytes,busy_code,comrat,
337 block_offset,block_size,i,j+1,&bError);
338 if (bError) return FALSE;
339 // up-left
340 L[i+1][j+1] = (L[i][j]+L[i][j+2]+L[i+2][j]+L[i+2][j+2])/4
341 + get_delta(srcdata,nInputBytes,busy_code,comrat,
342 block_offset,block_size,i+1,j+1,&bError);
343 if (bError) return FALSE;
344 }
345 }
346
347 return TRUE;
348 }
349
350 /************************************************************************/
351 /* NITFUncompressARIDPCM() */
352 /************************************************************************/
353
NITFUncompressARIDPCM(NITFImage * psImage,GByte * pabyInputData,int nInputBytes,GByte * pabyOutputImage)354 int NITFUncompressARIDPCM( NITFImage *psImage,
355 GByte *pabyInputData,
356 int nInputBytes,
357 GByte *pabyOutputImage )
358
359 {
360
361 /* -------------------------------------------------------------------- */
362 /* First, verify that we are a COMRAT 0.75 image, which is all */
363 /* we currently support. */
364 /* -------------------------------------------------------------------- */
365 if( !EQUAL(psImage->szCOMRAT,"0.75") )
366 {
367 CPLError( CE_Failure, CPLE_AppDefined,
368 "COMRAT=%s ARIDPCM is not supported.\n"
369 "Currently only 0.75 is supported.",
370 psImage->szCOMRAT );
371 return FALSE;
372 }
373
374 /* -------------------------------------------------------------------- */
375 /* Setup up the various info we need for each 8x8 neighbourhood */
376 /* (which we call blocks in this context). */
377 /* -------------------------------------------------------------------- */
378 int blocks_x = (psImage->nBlockWidth + 7) / 8;
379 int blocks_y = (psImage->nBlockHeight + 7) / 8;
380 int block_count = blocks_x * blocks_y;
381 int rowlen = blocks_x * 8;
382
383 if( psImage->nBlockWidth > 1000 || /* to detect int overflow above */
384 psImage->nBlockHeight > 1000 ||
385 block_count > 1000 )
386 {
387 CPLError( CE_Failure, CPLE_AppDefined, "Block too large to be decoded");
388 return FALSE;
389 }
390
391 int block_offset[1000];
392 int block_size[1000];
393 int busy_code[1000];
394 int busy_code_table_size = blocks_x * blocks_y * 2;
395 unsigned char L00[1000];
396
397 /* -------------------------------------------------------------------- */
398 /* We allocate a working copy of the full image that may be a */
399 /* bit larger than the output buffer if the width or height is */
400 /* not divisible by 8. */
401 /* -------------------------------------------------------------------- */
402 GByte *full_image = (GByte *) CPLMalloc(blocks_x * blocks_y * 8 * 8 );
403
404 /* -------------------------------------------------------------------- */
405 /* Scan through all the neighbourhoods determining the busyness */
406 /* code, and the offset to each's data as well as the L00 value. */
407 /* -------------------------------------------------------------------- */
408 int i, j, total = busy_code_table_size;
409
410 for( i = 0; i < blocks_x * blocks_y; i++ )
411 {
412 if (nInputBytes * 8 < i * 2 + 2)
413 {
414 CPLError( CE_Failure, CPLE_AppDefined, "Input buffer too small");
415 CPLFree(full_image);
416 return FALSE;
417 }
418 busy_code[i] = get_bits( pabyInputData, i*2, 2 );
419
420 block_offset[i] = total;
421 block_size[i] = neighbourhood_size_75[busy_code[i]];
422
423 if (nInputBytes * 8 < block_offset[i] + 8)
424 {
425 CPLError( CE_Failure, CPLE_AppDefined, "Input buffer too small");
426 CPLFree(full_image);
427 return FALSE;
428 }
429 L00[i] = (unsigned char) get_bits( pabyInputData, block_offset[i], 8 );
430
431 total += block_size[i];
432 }
433
434 /* -------------------------------------------------------------------- */
435 /* Process all the blocks, forming into a final image. */
436 /* -------------------------------------------------------------------- */
437 int iX, iY;
438
439 for( iY = 0; iY < blocks_y; iY++ )
440 {
441 for( iX = 0; iX < blocks_x; iX++ )
442 {
443 int iBlock = iX + iY * blocks_x;
444 int L[9][9];
445 unsigned char *full_tl = full_image + iX * 8 + iY * 8 * rowlen;
446
447 L[0][0] = L00[iBlock];
448 if( iX > 0 )
449 {
450 L[0][8] = full_tl[rowlen * 7 - 1];
451 L[2][8] = full_tl[rowlen * 5 - 1];
452 L[4][8] = full_tl[rowlen * 3 - 1];
453 L[6][8] = full_tl[rowlen * 1 - 1];
454 }
455 else
456 {
457 L[0][8] = L[0][0];
458 L[2][8] = L[0][8]; // need to reconstruct the rest!
459 L[4][8] = L[0][8];
460 L[6][8] = L[0][8];
461 }
462
463 if( iY > 0 )
464 {
465 L[8][0] = full_tl[7 - rowlen];
466 L[8][2] = full_tl[5 - rowlen];
467 L[8][4] = full_tl[3 - rowlen];
468 L[8][6] = full_tl[1 - rowlen];
469 }
470 else
471 {
472 L[8][0] = L[0][0];
473 L[8][2] = L[0][0]; // Need to reconstruct the rest!
474 L[8][4] = L[0][0];
475 L[8][5] = L[0][0];
476 }
477
478 if( iX == 0 || iY == 0 )
479 L[8][8] = L[0][0];
480 else
481 L[8][8] = full_tl[-1-rowlen];
482
483 if (!(decode_block( pabyInputData, nInputBytes, busy_code[iBlock], CR075,
484 block_offset[iBlock], block_size[iBlock],
485 iX == 0, iY == 0, L )))
486 {
487 CPLFree( full_image );
488 return FALSE;
489 }
490
491 // Assign to output matrix.
492 for( i = 0; i < 8; i++ )
493 {
494 for( j = 0; j < 8; j++ )
495 {
496 int value = L[i][j];
497 if( value < 0 )
498 value = 0;
499 if( value > 255 )
500 value = 255;
501
502 full_tl[8-j-1 + (8-i-1) * rowlen] = (unsigned char) value;
503 }
504 }
505 }
506 }
507
508 /* -------------------------------------------------------------------- */
509 /* Copy full image back into target buffer, and free. */
510 /* -------------------------------------------------------------------- */
511 for( iY = 0; iY < psImage->nBlockHeight; iY++ )
512 {
513 memcpy( pabyOutputImage + iY * psImage->nBlockWidth,
514 full_image + iY * rowlen,
515 psImage->nBlockWidth );
516 }
517
518 CPLFree( full_image );
519
520 return TRUE;
521 }
522