Skip to content

Commit 15fa71c

Browse files
kdt3rdcary-ilm
andauthored
Fix computation of chunk height (#2423)
* remove errant include Signed-off-by: Kimball Thurston <kdt3rd@gmail.com> * add test for combo of start line, lines per compression, y samples Signed-off-by: Kimball Thurston <kdt3rd@gmail.com> * fix compute of sampled height When there are strange y_sampling, the number of lines per chunk was not being computed correctly depending on how the start position lines up with the sampling Signed-off-by: Kimball Thurston <kdt3rd@gmail.com> * Apply suggestion from @cary-ilm remove debugging printf Signed-off-by: Cary Phillips <cary@ilm.com> * Apply suggestion from @cary-ilm remove debugging printf Signed-off-by: Cary Phillips <cary@ilm.com> --------- Signed-off-by: Kimball Thurston <kdt3rd@gmail.com> Signed-off-by: Cary Phillips <cary@ilm.com> Co-authored-by: Cary Phillips <cary@ilm.com>
1 parent f448690 commit 15fa71c

6 files changed

Lines changed: 138 additions & 13 deletions

File tree

src/lib/OpenEXRCore/internal_util.h

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#ifndef OPENEXR_PRIVATE_UTIL_H
77
#define OPENEXR_PRIVATE_UTIL_H
88

9+
#include <stdio.h>
910
#include <stdint.h>
1011

1112
static inline int
@@ -19,25 +20,27 @@ compute_sampled_height (int height, int y_sampling, int start_y)
1920
nlines = (start_y % y_sampling) == 0 ? 1 : 0;
2021
else
2122
{
22-
int start, end;
23+
int off, tmph;
2324

2425
/* computed the number of times y % ysampling == 0, by
2526
* computing interval based on first and last time that occurs
2627
* on the given range
2728
*/
28-
start = start_y % y_sampling;
29-
if (start != 0)
30-
start = start_y + (y_sampling - start);
29+
if (start_y < 0)
30+
{
31+
off = -start_y % y_sampling;
32+
}
3133
else
32-
start = start_y;
34+
{
35+
off = start_y % y_sampling;
36+
if (off != 0)
37+
off = (y_sampling - off);
38+
}
3339

34-
end = start_y + height - 1;
35-
end -= (end < 0 ? -end : end) % y_sampling;
36-
37-
if (start > end)
38-
nlines = start == start_y ? 1 : 0;
39-
else
40-
nlines = (end - start) / y_sampling + 1;
40+
tmph = height - off;
41+
if (tmph == 0) return 0;
42+
--tmph;
43+
nlines = tmph / y_sampling + 1;
4144
}
4245

4346
return nlines;

src/lib/OpenEXRCore/parse_header.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -748,7 +748,7 @@ extract_attr_tiledesc (
748748
}
749749

750750
/**************************************/
751-
#include <assert.h>
751+
752752
static exr_result_t
753753
extract_attr_bytes(
754754
exr_context_t ctxt,

src/test/OpenEXRCoreTest/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ define_openexrcore_tests(
9696
testReadMultiPart
9797
testReadDeep
9898
testReadUnpack
99+
testSamplingCalcs
99100

100101
testWriteBadArgs
101102
testWriteBadFiles

src/test/OpenEXRCoreTest/main.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,7 @@ main (int argc, char* argv[])
178178
TEST (testReadMultiPart, "core_read");
179179
TEST (testReadDeep, "core_read");
180180
TEST (testReadUnpack, "core_read");
181+
TEST (testSamplingCalcs, "core_read");
181182

182183
TEST (testWriteBadArgs, "core_write");
183184
TEST (testWriteBadFiles, "core_write");

src/test/OpenEXRCoreTest/read.cpp

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -616,3 +616,121 @@ testReadUnpack (const std::string& tempdir)
616616

617617
exr_finish (&f);
618618
}
619+
620+
#include "../../lib/OpenEXRCore/internal_util.h"
621+
622+
static inline int
623+
compute_sampled_height_p (int height, int y_sampling, int start_y)
624+
{
625+
int nlines;
626+
627+
if (y_sampling <= 1) return height;
628+
629+
if (height == 1)
630+
nlines = (start_y % y_sampling) == 0 ? 1 : 0;
631+
else
632+
{
633+
int off, tmph;
634+
635+
/* computed the number of times y % ysampling == 0, by
636+
* computing interval based on first and last time that occurs
637+
* on the given range
638+
*/
639+
if (start_y < 0)
640+
{
641+
off = -start_y % y_sampling;
642+
}
643+
else
644+
{
645+
off = start_y % y_sampling;
646+
if (off != 0)
647+
off = (y_sampling - off);
648+
}
649+
650+
tmph = height - off;
651+
if (tmph == 0) return 0;
652+
--tmph;
653+
nlines = tmph / y_sampling + 1;
654+
}
655+
656+
return nlines;
657+
}
658+
659+
static inline int hardway_height (int height, int y_sampling, int start_y)
660+
{
661+
int nlines = 0;
662+
int end = start_y + height;
663+
664+
if (y_sampling <= 1) return height;
665+
666+
if (height == 1)
667+
return (start_y % y_sampling) == 0 ? 1 : 0;
668+
669+
for ( int y = start_y; y < end; ++y )
670+
{
671+
if (y % y_sampling != 0) continue;
672+
++nlines;
673+
}
674+
return nlines;
675+
}
676+
677+
static inline int hardway_height_p (int height, int y_sampling, int start_y)
678+
{
679+
int nlines = 0;
680+
int end = start_y + height;
681+
int off = 0;
682+
683+
if (y_sampling <= 1) return height;
684+
685+
if (height == 1)
686+
return (start_y % y_sampling) == 0 ? 1 : 0;
687+
688+
for ( int y = start_y; y < end; ++y )
689+
{
690+
if (y % y_sampling != 0)
691+
{
692+
if (nlines == 0) ++off;
693+
continue;
694+
}
695+
++nlines;
696+
}
697+
return nlines;
698+
}
699+
700+
static void test_lpc( int samp, int h, int lpc )
701+
{
702+
for ( int y = -100; y < 100; ++y )
703+
{
704+
int sy = y * samp;
705+
int ey = sy + h - 1;
706+
//printf( "============= %d - %d ============\n", sy, ey);
707+
for ( int ty = sy; ty < ey; ty += lpc )
708+
{
709+
int th = ty + lpc;
710+
if (th > ey) th = ey - ty + 1;
711+
else th = lpc;
712+
713+
int nl = compute_sampled_height(th, samp, ty);
714+
int hnl = hardway_height(th, samp, ty);
715+
if (nl != hnl)
716+
{
717+
compute_sampled_height_p(th, samp, ty);
718+
hardway_height_p(th, samp, ty);
719+
printf( "ty %d h %d (%d) samp %d lpc %d => nl %d hnl %d\n",
720+
ty, th, h, samp, lpc, nl, hnl );
721+
EXRCORE_TEST(nl == hnl);
722+
}
723+
}
724+
}
725+
}
726+
727+
void testSamplingCalcs (const std::string& tempdir)
728+
{
729+
int lines[] = { 1, 16, 32, 256 };
730+
731+
for ( int s = 2; s < 11; ++s )
732+
{
733+
for ( int lpc = 0; lpc < 4; ++lpc )
734+
test_lpc( s, 1000, lines[lpc] );
735+
}
736+
}

src/test/OpenEXRCoreTest/read.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,4 +22,6 @@ void testReadMultiPart (const std::string& tempdir);
2222

2323
void testReadUnpack (const std::string& tempdir);
2424

25+
void testSamplingCalcs (const std::string& tempdir);
26+
2527
#endif // OPENEXR_CORE_TEST_READ_H

0 commit comments

Comments
 (0)