@@ -975,8 +975,21 @@ namespace ojph {
975975 OJPH_ERROR (0x00050079 , " error reading COD segment" );
976976 if (file->read (&SPcod.wavelet_trans , 1 ) != 1 )
977977 OJPH_ERROR (0x0005007A , " error reading COD segment" );
978+
979+ if (get_num_decompositions () > 32
980+ || SPcod.block_width > 8
981+ || SPcod.block_height > 8
982+ || SPcod.block_width + SPcod.block_height > 8
983+ || (SPcod.block_style & 0x40 ) != 0x40
984+ || (SPcod.block_style & 0xB7 ) != 0x00 )
985+ OJPH_ERROR (0x0005007D , " wrong settings in a COD-SPcod parameter" );
986+ if ((SPcod.block_style & 0x40 ) != 0x40
987+ || (SPcod.block_style & 0xB7 ) != 0x00 )
988+ OJPH_ERROR (0x0005007E , " unsupported settings in a COD-SPcod parameter" );
989+
990+ ui8 num_decompositions = get_num_decompositions ();
978991 if (Scod & 1 )
979- for (int i = 0 ; i <= SPcod. num_decomp ; ++i)
992+ for (int i = 0 ; i <= num_decompositions ; ++i)
980993 if (file->read (&SPcod.precinct_size [i], 1 ) != 1 )
981994 OJPH_ERROR (0x0005007B , " error reading COD segment" );
982995 if (Lcod != 12 + ((Scod & 1 ) ? 1 + SPcod.num_decomp : 0 ))
@@ -1021,13 +1034,26 @@ namespace ojph {
10211034 OJPH_ERROR (0x00050128 , " error reading COC segment" );
10221035 if (file->read (&SPcod.wavelet_trans , 1 ) != 1 )
10231036 OJPH_ERROR (0x00050129 , " error reading COC segment" );
1037+
1038+ if (get_num_decompositions () > 32
1039+ || SPcod.block_width > 8
1040+ || SPcod.block_height > 8
1041+ || SPcod.block_width + SPcod.block_height > 8
1042+ || (SPcod.block_style & 0x40 ) != 0x40
1043+ || (SPcod.block_style & 0xB7 ) != 0x00 )
1044+ OJPH_ERROR (0x0005012C , " wrong settings in a COC-SPcoc parameter" );
1045+ if ((SPcod.block_style & 0x40 ) != 0x40
1046+ || (SPcod.block_style & 0xB7 ) != 0x00 )
1047+ OJPH_ERROR (0x0005012D , " unsupported settings in a COC-SPcoc parameter" );
1048+
1049+ ui8 num_decompositions = get_num_decompositions ();
10241050 if (Scod & 1 )
1025- for (int i = 0 ; i <= get_num_decompositions () ; ++i)
1051+ for (int i = 0 ; i <= num_decompositions ; ++i)
10261052 if (file->read (&SPcod.precinct_size [i], 1 ) != 1 )
10271053 OJPH_ERROR (0x0005012A , " error reading COC segment" );
10281054 ui32 t = 9 ;
10291055 t += num_comps < 257 ? 0 : 1 ;
1030- t += (Scod & 1 ) ? 1 + get_num_decompositions () : 0 ;
1056+ t += (Scod & 1 ) ? 1 + num_decompositions : 0 ;
10311057 if (Lcod != t)
10321058 OJPH_ERROR (0x0005012B , " error in COC segment length" );
10331059 }
@@ -1625,8 +1651,8 @@ namespace ojph {
16251651 if ((Sqcd & 0x1F ) == 0 )
16261652 {
16271653 num_subbands = (Lqcd - 3 );
1628- if (Lqcd != 3 + num_subbands)
1629- OJPH_ERROR (0x00050083 , " wrong Lqcd value in QCD marker" );
1654+ if (num_subbands > 97 || Lqcd != 3 + num_subbands)
1655+ OJPH_ERROR (0x00050083 , " wrong Lqcd value of %d in QCD marker" , Lqcd );
16301656 for (ui32 i = 0 ; i < num_subbands; ++i)
16311657 if (file->read (&SPqcd.u8 [i], 1 ) != 1 )
16321658 OJPH_ERROR (0x00050084 , " error reading QCD marker" );
@@ -1642,8 +1668,8 @@ namespace ojph {
16421668 else if ((Sqcd & 0x1F ) == 2 )
16431669 {
16441670 num_subbands = (Lqcd - 3 ) / 2 ;
1645- if (Lqcd != 3 + 2 * num_subbands)
1646- OJPH_ERROR (0x00050086 , " wrong Lqcd value in QCD marker" );
1671+ if (num_subbands > 97 || Lqcd != 3 + 2 * num_subbands)
1672+ OJPH_ERROR (0x00050086 , " wrong Lqcd value of %d in QCD marker" , Lqcd );
16471673 for (ui32 i = 0 ; i < num_subbands; ++i)
16481674 {
16491675 if (file->read (&SPqcd.u16 [i], 2 ) != 2 )
@@ -1680,8 +1706,8 @@ namespace ojph {
16801706 if ((Sqcd & 0x1F ) == 0 )
16811707 {
16821708 num_subbands = (Lqcd - offset);
1683- if (Lqcd != offset + num_subbands)
1684- OJPH_ERROR (0x000500A5 , " wrong Lqcd value in QCC marker" );
1709+ if (num_subbands > 97 || Lqcd != offset + num_subbands)
1710+ OJPH_ERROR (0x000500A5 , " wrong Lqcd value of %d in QCC marker" , Lqcd );
16851711 for (ui32 i = 0 ; i < num_subbands; ++i)
16861712 if (file->read (&SPqcd.u8 [i], 1 ) != 1 )
16871713 OJPH_ERROR (0x000500A6 , " error reading QCC marker" );
@@ -1697,8 +1723,8 @@ namespace ojph {
16971723 else if ((Sqcd & 0x1F ) == 2 )
16981724 {
16991725 num_subbands = (Lqcd - offset) / 2 ;
1700- if (Lqcd != offset + 2 * num_subbands)
1701- OJPH_ERROR (0x000500A8 , " wrong Lqcc value in QCC marker" );
1726+ if (num_subbands > 97 || Lqcd != offset + 2 * num_subbands)
1727+ OJPH_ERROR (0x000500A8 , " wrong Lqcc value of %d in QCC marker" , Lqcd );
17021728 for (ui32 i = 0 ; i < num_subbands; ++i)
17031729 {
17041730 if (file->read (&SPqcd.u16 [i], 2 ) != 2 )
@@ -2314,7 +2340,7 @@ namespace ojph {
23142340 // ////////////////////////////////////////////////////////////////////////
23152341 param_atk* param_atk::get_atk (int index)
23162342 {
2317- assert (type == OJPH_ATK_TOP );
2343+ assert (top_atk == NULL );
23182344
23192345 if (Latk == 0 )
23202346 {
@@ -2345,17 +2371,19 @@ namespace ojph {
23452371 }
23462372
23472373 // ////////////////////////////////////////////////////////////////////////
2348- bool param_atk::read_coefficient (infile_base *file, float &K)
2374+ bool param_atk::read_coefficient (infile_base *file, float &K, si32& bytes )
23492375 {
23502376 int coeff_type = get_coeff_type ();
23512377 if (coeff_type == 0 ) { // 8bit
23522378 ui8 v;
23532379 if (file->read (&v, 1 ) != 1 ) return false ;
2380+ bytes -= 1 ;
23542381 K = v;
23552382 }
23562383 else if (coeff_type == 1 ) { // 16bit
23572384 ui16 v;
23582385 if (file->read (&v, 2 ) != 2 ) return false ;
2386+ bytes -= 2 ;
23592387 K = swap_byte (v);
23602388 }
23612389 else if (coeff_type == 2 ) { // float
@@ -2364,6 +2392,7 @@ namespace ojph {
23642392 ui32 i;
23652393 } v;
23662394 if (file->read (&v.i , 4 ) != 4 ) return false ;
2395+ bytes -= 4 ;
23672396 v.i = swap_byte (v.i );
23682397 K = v.f ;
23692398 }
@@ -2373,13 +2402,16 @@ namespace ojph {
23732402 ui64 i;
23742403 } v;
23752404 if (file->read (&v.i , 8 ) != 8 ) return false ;
2405+ bytes -= 8 ;
23762406 v.i = swap_byte (v.i );
23772407 K = (float )v.d ;
23782408 }
23792409 else if (coeff_type == 4 ) { // 128 bit float
23802410 ui64 v, v1;
23812411 if (file->read (&v, 8 ) != 8 ) return false ;
2412+ bytes -= 8 ;
23822413 if (file->read (&v1, 8 ) != 8 ) return false ; // v1 not needed
2414+ bytes -= 8 ;
23832415 v = swap_byte (v);
23842416
23852417 union {
@@ -2405,17 +2437,19 @@ namespace ojph {
24052437
24062438
24072439 // ////////////////////////////////////////////////////////////////////////
2408- bool param_atk::read_coefficient (infile_base *file, si16 &K)
2440+ bool param_atk::read_coefficient (infile_base *file, si16 &K, si32& bytes )
24092441 {
24102442 int coeff_type = get_coeff_type ();
24112443 if (coeff_type == 0 ) {
24122444 si8 v;
24132445 if (file->read (&v, 1 ) != 1 ) return false ;
2446+ bytes -= 1 ;
24142447 K = v;
24152448 }
24162449 else if (coeff_type == 1 ) {
24172450 si16 v;
24182451 if (file->read (&v, 2 ) != 2 ) return false ;
2452+ bytes -= 2 ;
24192453 K = (si16)swap_byte ((ui16)v);
24202454 }
24212455 else
@@ -2432,16 +2466,19 @@ namespace ojph {
24322466 if (file->read (&Latk, 2 ) != 2 )
24332467 OJPH_ERROR (0x000500E1 , " error reading ATK-Latk parameter" );
24342468 Latk = swap_byte (Latk);
2469+ si32 bytes = Latk - 2 ;
24352470 ojph::ui16 temp_Satk;
24362471 if (file->read (&temp_Satk, 2 ) != 2 )
24372472 OJPH_ERROR (0x000500E2 , " error reading ATK-Satk parameter" );
2473+ bytes -= 2 ;
24382474 temp_Satk = swap_byte (temp_Satk);
24392475 int tmp_idx = temp_Satk & 0xFF ;
2440- if (tmp_idx == 0 || tmp_idx == 1 || top_atk->get_atk (tmp_idx) != NULL )
2476+ if ((top_atk && top_atk->get_atk (tmp_idx) != NULL )
2477+ || tmp_idx == 0 || tmp_idx == 1 )
24412478 OJPH_ERROR (0x000500F3 , " ATK-Satk parameter sets ATK marker index to "
24422479 " the illegal value of %d. ATK-Satk should be in (2-255) and, I "
24432480 " believe, must not be repeated; otherwise, it would be unclear "
2444- " what marker segment must be employed when this index is used ." ,
2481+ " what marker segment must be employed when an index is repeated ." ,
24452482 tmp_idx);
24462483 Satk = temp_Satk;
24472484 if (is_m_init0 () == false ) // only even-indexed is supported
@@ -2458,10 +2495,11 @@ namespace ojph {
24582495 OJPH_ERROR (0x000500E6 , " ATK-Satk parameter requires constant "
24592496 " boundary extension, which is not supported yet." );
24602497 if (is_reversible () == false )
2461- if (read_coefficient (file, Katk) == false )
2498+ if (read_coefficient (file, Katk, bytes ) == false )
24622499 OJPH_ERROR (0x000500E7 , " error reading ATK-Katk parameter" );
24632500 if (file->read (&Natk, 1 ) != 1 )
24642501 OJPH_ERROR (0x000500E8 , " error reading ATK-Natk parameter" );
2502+ bytes -= 1 ;
24652503 if (Natk > max_steps) {
24662504 if (d != d_store) // was this allocated -- very unlikely
24672505 delete[] d;
@@ -2475,19 +2513,22 @@ namespace ojph {
24752513 {
24762514 if (file->read (&d[s].rev .Eatk , 1 ) != 1 )
24772515 OJPH_ERROR (0x000500E9 , " error reading ATK-Eatk parameter" );
2516+ bytes -= 1 ;
24782517 if (file->read (&d[s].rev .Batk , 2 ) != 2 )
24792518 OJPH_ERROR (0x000500EA , " error reading ATK-Batk parameter" );
2519+ bytes -= 2 ;
24802520 d[s].rev .Batk = (si16)swap_byte ((ui16)d[s].rev .Batk );
24812521 ui8 LCatk;
24822522 if (file->read (&LCatk, 1 ) != 1 )
24832523 OJPH_ERROR (0x000500EB , " error reading ATK-LCatk parameter" );
2524+ bytes -= 1 ;
24842525 if (LCatk == 0 )
24852526 OJPH_ERROR (0x000500EC , " Encountered a ATK-LCatk value of zero; "
24862527 " something is wrong." );
24872528 if (LCatk > 1 )
24882529 OJPH_ERROR (0x000500ED , " ATK-LCatk value greater than 1; "
24892530 " that is, a multitap filter is not supported" );
2490- if (read_coefficient (file, d[s].rev .Aatk ) == false )
2531+ if (read_coefficient (file, d[s].rev .Aatk , bytes ) == false )
24912532 OJPH_ERROR (0x000500EE , " Error reding ATK-Aatk parameter" );
24922533 }
24932534 }
@@ -2498,16 +2539,20 @@ namespace ojph {
24982539 ui8 LCatk;
24992540 if (file->read (&LCatk, 1 ) != 1 )
25002541 OJPH_ERROR (0x000500EF , " error reading ATK-LCatk parameter" );
2542+ bytes -= 1 ;
25012543 if (LCatk == 0 )
25022544 OJPH_ERROR (0x000500F0 , " Encountered a ATK-LCatk value of zero; "
25032545 " something is wrong." );
25042546 if (LCatk > 1 )
25052547 OJPH_ERROR (0x000500F1 , " ATK-LCatk value greater than 1; "
25062548 " that is, a multitap filter is not supported." );
2507- if (read_coefficient (file, d[s].irv .Aatk ) == false )
2549+ if (read_coefficient (file, d[s].irv .Aatk , bytes ) == false )
25082550 OJPH_ERROR (0x000500F2 , " Error reding ATK-Aatk parameter" );
25092551 }
25102552 }
2553+ if (bytes != 0 )
2554+ OJPH_ERROR (0x000500F3 , " The length of an ATK marker segment "
2555+ " (ATK-Latk) is not correct" );
25112556
25122557 return true ;
25132558 }
@@ -2544,20 +2589,20 @@ namespace ojph {
25442589 // ////////////////////////////////////////////////////////////////////////
25452590 param_atk* param_atk::add_object ()
25462591 {
2547- assert (type == OJPH_ATK_TOP );
2592+ assert (top_atk = NULL );
25482593 param_atk *p = this ;
25492594 while (p->next != NULL )
25502595 p = p->next ;
25512596 if (avail)
25522597 {
25532598 p->next = avail;
25542599 avail = avail->next ;
2555- assert (p->next ->type == OJPH_ATK_NONTOP);
2556- p->next ->init (this );
25572600 }
25582601 else
2559- p->next = new param_atk (this , OJPH_ATK_NONTOP);
2560- return p->next ;
2602+ p->next = new param_atk;
2603+ p = p->next ;
2604+ p->init (this );
2605+ return p;
25612606 }
25622607
25632608 } // !local namespace
0 commit comments