@@ -463,13 +463,11 @@ namespace ojph {
463463 if (marker_idx == 0 )
464464 cap.read (file);
465465 else if (marker_idx == 1 )
466- skip_marker (file, " PRF" ,
467- " Skipping PRF marker segment; this should not cause any issues." ,
468- OJPH_MSG_LEVEL::NO_MSG);
466+ // Skipping PRF marker segment; this should not cause any issues
467+ skip_marker (file, " PRF" , NULL , OJPH_MSG_LEVEL::NO_MSG);
469468 else if (marker_idx == 2 )
470- skip_marker (file, " CPF" ,
471- " Skipping CPF marker segment; this should not cause any issues." ,
472- OJPH_MSG_LEVEL::NO_MSG);
469+ // Skipping CPF marker segment; this should not cause any issues
470+ skip_marker (file, " CPF" , NULL , OJPH_MSG_LEVEL::NO_MSG);
473471 else if (marker_idx == 3 )
474472 { cod.read (file); received_markers |= 1 ; }
475473 else if (marker_idx == 4 )
@@ -490,14 +488,19 @@ namespace ojph {
490488 skip_marker (file, " PPM" , " PPM is not supported yet" ,
491489 OJPH_MSG_LEVEL::WARN);
492490 else if (marker_idx == 10 )
493- skip_marker (file, " TLM" , " TLM is not supported yet " ,
494- OJPH_MSG_LEVEL::WARN );
491+ // Skipping TLM marker segment; this should not cause any issues
492+ skip_marker (file, " TLM " , NULL , OJPH_MSG_LEVEL::NO_MSG );
495493 else if (marker_idx == 11 )
496- skip_marker (file, " PLM" , " PLM is not supported yet " ,
497- OJPH_MSG_LEVEL::WARN );
494+ // Skipping PLM marker segment; this should not cause any issues
495+ skip_marker (file, " PLM " , NULL , OJPH_MSG_LEVEL::NO_MSG );
498496 else if (marker_idx == 12 )
499- skip_marker (file, " CRG" , " CRG is not supported yet" ,
500- OJPH_MSG_LEVEL::WARN);
497+ // Skipping CRG marker segment;
498+ skip_marker (file, " CRG" , " CRG has been ignored; CRG is related to"
499+ " where the Cb and Cr colour components are co-sited or located"
500+ " with respect to the Y' luma component. Perhaps, it is better"
501+ " to get the indivdual components and assemble the samples"
502+ " according to your needs" ,
503+ OJPH_MSG_LEVEL::INFO);
501504 else if (marker_idx == 13 )
502505 skip_marker (file, " COM" , NULL , OJPH_MSG_LEVEL::NO_MSG);
503506 else if (marker_idx == 14 )
@@ -523,6 +526,7 @@ namespace ojph {
523526 {
524527 param_sot_t sot;
525528 sot.read (infile);
529+ ui64 tile_start_location = infile->tell ();
526530
527531 if (sot.get_tile_index () > (int )num_tiles.area ())
528532 OJPH_ERROR (0x00030061 , " wrong tile index" );
@@ -547,16 +551,17 @@ namespace ojph {
547551 skip_marker (infile, " PPT" , " PPT in a tile is not supported yet" ,
548552 OJPH_MSG_LEVEL::WARN);
549553 else if (marker_idx == 2 )
550- skip_marker (infile, " PLT" , " PLT in a tile is not supported yet " ,
551- OJPH_MSG_LEVEL::WARN );
554+ // Skipping PLT marker segment; this should not cause any issues
555+ skip_marker (infile, " PLT " , NULL , OJPH_MSG_LEVEL::NO_MSG );
552556 else if (marker_idx == 3 )
553557 skip_marker (infile, " COM" , NULL , OJPH_MSG_LEVEL::NO_MSG);
554558 else if (marker_idx == 4 )
555559 break ;
556560 else
557561 OJPH_ERROR (0x00030063 , " unknown marker in a tile header" );
558562 }
559- tiles[sot.get_tile_index ()].parse_tile_header (sot, infile);
563+ tiles[sot.get_tile_index ()].parse_tile_header (sot, infile,
564+ tile_start_location);
560565 }
561566 else
562567 { // first tile part
@@ -588,24 +593,25 @@ namespace ojph {
588593 skip_marker (infile, " PPT" , " PPT in a tile is not supported yet" ,
589594 OJPH_MSG_LEVEL::WARN);
590595 else if (marker_idx == 7 )
591- skip_marker (infile, " PLT" , " PLT in a tile is not supported yet " ,
592- OJPH_MSG_LEVEL::WARN );
596+ // Skipping PLT marker segment; this should not cause any issues
597+ skip_marker (infile, " PLT " , NULL , OJPH_MSG_LEVEL::NO_MSG );
593598 else if (marker_idx == 8 )
594599 skip_marker (infile, " COM" , NULL , OJPH_MSG_LEVEL::NO_MSG);
595600 else if (marker_idx == 9 )
596601 break ;
597602 else
598603 OJPH_ERROR (0x00030064 , " unknown marker in a tile header" );
599604 }
600- tiles[sot.get_tile_index ()].parse_tile_header (sot, infile);
605+ tiles[sot.get_tile_index ()].parse_tile_header (sot, infile,
606+ tile_start_location);
601607 }
602608 // check the next marker; either SOT or EOC,
603609 // if something is broken, just an end of file
604610 ui16 next_markers[2 ] = { SOT, EOC };
605611 int marker_idx = find_marker (infile, next_markers, 2 );
606612 if (marker_idx == -1 )
607613 {
608- OJPH_ERROR ( 0x00030065 , " file termianted early" );
614+ OJPH_INFO ( 0x00030021 , " file terminated early" );
609615 break ;
610616 }
611617 else if (marker_idx == 0 )
@@ -1147,16 +1153,26 @@ namespace ojph {
11471153 }
11481154
11491155 // ////////////////////////////////////////////////////////////////////////
1150- void tile::parse_tile_header (const param_sot_t &sot, infile_base *file)
1156+ void tile::parse_tile_header (const param_sot_t &sot, infile_base *file,
1157+ const ui64& tile_start_location)
11511158 {
1152- if (this -> sot .get_tile_part_index () != next_tile_part)
1159+ if (sot.get_tile_part_index () != next_tile_part)
11531160 OJPH_ERROR (0x00030091 , " wrong tile part index" );
11541161 this ->sot .append (sot.get_length ());
11551162 ++next_tile_part;
11561163
1157- long tile_end_location = file->tell () + sot.get_length ();// used on
1158- // failure
1164+ // tile_end_location used on failure
1165+ ui64 tile_end_location = tile_start_location + sot.get_length ();
1166+
11591167 int data_left = sot.get_length (); // how many bytes left to parse
1168+ data_left -= file->tell () - tile_start_location;
1169+ data_left += 2 ; // 2 is the size of SOD
1170+
1171+ if (data_left == 0 )
1172+ return ;
1173+ else if (data_left < 0 )
1174+ OJPH_ERROR (0x00030092 , " a tile part that has less than 0 bytes;"
1175+ " something is wrong" );
11601176
11611177 int max_decompositions = 0 ;
11621178 for (int c = 0 ; c < num_comps; ++c)
@@ -1170,7 +1186,8 @@ namespace ojph {
11701186 {
11711187 for (int r = 0 ; r <= max_decompositions; ++r)
11721188 for (int c = 0 ; c < num_comps; ++c)
1173- comps[c].parse_precincts (r, data_left, file);
1189+ if (data_left > 0 )
1190+ comps[c].parse_precincts (r, data_left, file);
11741191 }
11751192 else if (prog_order == OJPH_PO_RPCL)
11761193 {
@@ -1189,7 +1206,7 @@ namespace ojph {
11891206 else if (cur.y == smallest.y && cur.x < smallest.x )
11901207 { smallest = cur; comp_num = c; }
11911208 }
1192- if (comp_num >= 0 )
1209+ if (comp_num >= 0 && data_left > 0 )
11931210 comps[comp_num].parse_one_precinct (r, data_left, file);
11941211 else
11951212 break ;
@@ -1221,7 +1238,7 @@ namespace ojph {
12211238 { smallest = cur; comp_num = c; res_num = r; }
12221239 }
12231240 }
1224- if (comp_num >= 0 )
1241+ if (comp_num >= 0 && data_left > 0 )
12251242 comps[comp_num].parse_one_precinct (res_num, data_left, file);
12261243 else
12271244 break ;
@@ -1244,7 +1261,7 @@ namespace ojph {
12441261 else if (cur.y == smallest.y && cur.x < smallest.x )
12451262 { smallest = cur; res_num = r; }
12461263 }
1247- if (res_num >= 0 )
1264+ if (res_num >= 0 && data_left > 0 )
12481265 comps[c].parse_one_precinct (res_num, data_left, file);
12491266 else
12501267 break ;
@@ -1257,7 +1274,7 @@ namespace ojph {
12571274 }
12581275 catch (const char *error)
12591276 {
1260- OJPH_WARN (0x00030011 , " %s\n " , error);
1277+ OJPH_INFO (0x00030011 , " %s\n " , error);
12611278 }
12621279 file->seek (tile_end_location, infile_base::OJPH_SEEK_SET);
12631280 }
@@ -1627,6 +1644,8 @@ namespace ojph {
16271644 pp->special_y = test_y && y == 0 ;
16281645 pp->num_bands = num_bands;
16291646 pp->bands = bands;
1647+ pp->may_use_sop = cd.packets_may_use_sop ();
1648+ pp->uses_eph = cd.packets_use_eph ();
16301649 }
16311650 }
16321651 if (num_bands == 1 )
@@ -2130,7 +2149,7 @@ namespace ojph {
21302149 int idx = cur_precinct_loc.x + cur_precinct_loc.y * num_precincts.w ;
21312150 for (size_t i = idx; i < num_precincts.area (); ++i)
21322151 {
2133- if (data_left = = 0 )
2152+ if (data_left < = 0 )
21342153 break ;
21352154 p[i].parse (tag_tree_size, level_index, elastic, data_left, file);
21362155 if (++cur_precinct_loc.x >= num_precincts.w )
@@ -2147,7 +2166,7 @@ namespace ojph {
21472166 int idx = cur_precinct_loc.x + cur_precinct_loc.y * num_precincts.w ;
21482167 assert (idx < (int )num_precincts.area ());
21492168
2150- if (data_left = = 0 )
2169+ if (data_left < = 0 )
21512170 return ;
21522171 precinct *p = precincts + idx;
21532172 p->parse (tag_tree_size, level_index, elastic, data_left, file);
@@ -2663,17 +2682,72 @@ namespace ojph {
26632682
26642683 // ////////////////////////////////////////////////////////////////////////
26652684 static inline
2666- bool terminate (bit_read_buf *bbp)
2685+ void bb_skip_eph (bit_read_buf *bbp)
2686+ {
2687+ if (bbp->bytes_left >= 2 )
2688+ {
2689+ ui8 marker[2 ];
2690+ if (bbp->file ->read (marker, 2 ) != 2 )
2691+ throw " error reading from file" ;
2692+ bbp->bytes_left -= 2 ;
2693+ if ((int )marker[0 ] != (EPH >> 8 ) || (int )marker[1 ] != (EPH & 0xFF ))
2694+ throw " should find EPH, but found something else" ;
2695+ }
2696+ }
2697+
2698+ // ////////////////////////////////////////////////////////////////////////
2699+ static inline
2700+ bool bb_terminate (bit_read_buf *bbp, bool uses_eph)
26672701 {
26682702 bool result = true ;
26692703 if (bbp->unstuff )
26702704 result = bb_read (bbp);
26712705 assert (bbp->unstuff == false );
2706+ if (uses_eph)
2707+ bb_skip_eph (bbp);
26722708 bbp->tmp = 0 ;
26732709 bbp->avail_bits = 0 ;
26742710 return result;
26752711 }
26762712
2713+ // ////////////////////////////////////////////////////////////////////////
2714+ static inline
2715+ bool bb_skip_sop (bit_read_buf *bbp)
2716+ {
2717+ if (bbp->bytes_left >= 2 )
2718+ {
2719+ ui8 marker[2 ];
2720+ if (bbp->file ->read (marker, 2 ) != 2 )
2721+ throw " error reading from file" ;
2722+ if ((int )marker[0 ] == (SOP >> 8 ) && (int )marker[1 ] == (SOP & 0xFF ))
2723+ {
2724+ bbp->bytes_left -= 2 ;
2725+ if (bbp->bytes_left >= 4 )
2726+ {
2727+ ui16 com_len;
2728+ if (bbp->file ->read (&com_len, 2 ) != 2 )
2729+ OJPH_ERROR (0x000300A1 , " error reading from file" );
2730+ com_len = swap_byte (com_len);
2731+ if (bbp->file ->seek (com_len - 2 , infile_base::OJPH_SEEK_CUR) != 0 )
2732+ throw " error seeking file" ;
2733+ bbp->bytes_left -= com_len;
2734+ if (com_len != 4 )
2735+ throw " something is wrong with SOP length" ;
2736+ }
2737+ return true ;
2738+ }
2739+ else
2740+ {
2741+ // put the bytes back
2742+ if (bbp->file ->seek (-2 , infile_base::OJPH_SEEK_CUR) != 0 )
2743+ throw " error seeking file" ;
2744+ return false ;
2745+ }
2746+ }
2747+
2748+ return false ;
2749+ }
2750+
26772751 // ////////////////////////////////////////////////////////////////////////
26782752 void precinct::parse (int tag_tree_size, si32* lev_idx,
26792753 mem_elastic_allocator *elastic,
@@ -2682,6 +2756,8 @@ namespace ojph {
26822756 assert (data_left);
26832757 bit_read_buf bb;
26842758 bb_init (&bb, data_left, file);
2759+ if (may_use_sop)
2760+ bb_skip_sop (&bb);
26852761
26862762 int sst = num_bands == 3 ? 1 : 0 ;
26872763 int send = num_bands == 3 ? 4 : 1 ;
@@ -2696,7 +2772,7 @@ namespace ojph {
26962772 ui32 bit;
26972773 bb_read_bit (&bb, bit);
26982774 if (bit == 0 ) // empty packet
2699- { terminate (&bb); data_left = bb.bytes_left ; return ; }
2775+ { bb_terminate (&bb, uses_eph ); data_left = bb.bytes_left ; return ; }
27002776 empty_packet = false ;
27012777 }
27022778
@@ -2830,7 +2906,7 @@ namespace ojph {
28302906 }
28312907 }
28322908 }
2833- terminate (&bb);
2909+ bb_terminate (&bb, uses_eph );
28342910 // read codeblock data
28352911 for (int s = sst; s < send; ++s)
28362912 {
0 commit comments