Skip to content

Commit 088712e

Browse files
Merge branch 'main' into AlexeySmolenchuk-patch-1
2 parents 5d14160 + af39d5a commit 088712e

File tree

6 files changed

+462
-233
lines changed

6 files changed

+462
-233
lines changed

TODO

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
Color Correction
2-
[ ] auto find range
2+
[x] auto find range
33

44
[ ] Inspect Values from Texture Data
5-
5+
[x] From cache
6+
[ ] Schedule image stats upfront asynchronously
67
OCIO
78
[ ] OCIO config selector
89
[ ] OCIO transform selector
@@ -12,7 +13,6 @@ OCIO
1213
[ ] Selective Float/Half/int16/int8 precision
1314
[ ] Alpha checking
1415

15-
[ ] Display info about storage and compression
1616
[ ] Display metadata
1717

1818
[ ] Add Help
@@ -21,13 +21,16 @@ OCIO
2121

2222

2323
List of shortcuts:
24+
F1 Help
2425
` 1 2 3 4 (top row) RGB/R/G/B/A
2526
0 - = (top row) Exposure Reset/EV-/EV+
27+
R Adjust Gain and Offset to fit Range
2628
[ Next AOV
2729
] Previous AOV
2830
PgUp PgDn Next/Previous MIP
2931
F Fit/100%
3032
I Inspect Tool
33+
F5 Reload image
3134
F11 Fullscreen
3235
H Hide UI
3336
+ - (numpad) ZoomIn/ZoomOut

src/imagePlane.cpp

Lines changed: 91 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,21 @@
11

22
#include "imagePlane.h"
3+
#include <OpenImageIO/imagebuf.h>
4+
#include <OpenImageIO/imagebufalgo.h>
5+
#include <float.h>
36

47
void ImagePlaneData::load()
58
{
6-
using namespace OIIO;
9+
if (ready != ISSUED)
10+
return;
711

8-
// std::cout << name << groupName << channels << std::endl;
912
ready = LOADING_STARTED;
10-
13+
14+
using namespace OIIO;
15+
16+
float missing[4] = { 0.0, 0.0, 0.0, 0.0 };
17+
OIIO::attribute ("missingcolor", TypeDesc("float[4]"), &missing);
18+
1119
auto inp = ImageInput::open (imageFileName);
1220
if (! inp)
1321
{
@@ -20,30 +28,93 @@ void ImagePlaneData::load()
2028
* imageHeight
2129
* len];
2230

23-
if (! inp->read_image( subimage,
24-
mip,
25-
begin,
26-
begin + len,
27-
TypeDesc::PRECISION,
28-
&pixels[0]))
31+
buffer = ImageBuf(imageFileName, subimage, mip, cache);
32+
33+
// Preload first imagePlane
34+
if (begin==0)
2935
{
30-
std::cerr << "Could not read pixels from " << imageFileName
31-
<< ", error = " << inp->geterror() << "\n";
32-
return;
36+
bool ok = buffer.read(subimage, mip, begin, begin + len, true, TypeDesc::PRECISION);
37+
if (!ok)
38+
std::cout << buffer.geterror() << std::endl;
39+
}
40+
41+
42+
ROI roi = buffer.spec().roi();
43+
roi.chbegin = begin;
44+
roi.chend = begin + len;
45+
46+
bool ok = buffer.get_pixels(roi, TypeDesc::PRECISION, &pixels[0]);
47+
if (!ok)
48+
std::cout << buffer.geterror() << std::endl;
49+
50+
// cache->get_pixels(ustring(imageFileName), subimage, mip, 0, imageWidth, 0, imageHeight, 0, 1, begin, begin + len, TypeDesc::PRECISION, &pixels[0]);
51+
52+
// if (! inp->read_image( subimage,
53+
// mip,
54+
// begin,
55+
// begin + len,
56+
// TypeDesc::PRECISION,
57+
// &pixels[0]))
58+
// {
59+
// std::cerr << "Could not read pixels from " << imageFileName
60+
// << ", error = " << inp->geterror() << "\n";
61+
// return;
62+
// }
63+
// if (! inp->close ())
64+
// {
65+
// std::cerr << "Error closing " << imageFileName
66+
// << ", error = " << inp->geterror() << "\n";
67+
// return;
68+
// }
69+
70+
ready = LOADED;
71+
}
72+
73+
74+
template<typename BUFT>
75+
static void getRange_impl(ImagePlaneData *plane, float *minimum, float *maximum)
76+
{
77+
for (OIIO::ImageBuf::ConstIterator<BUFT> it(plane->buffer); !it.done(); ++it)
78+
{
79+
int i = 0;
80+
for (int c = plane->begin; c < plane->begin+plane->len; ++c)
81+
{
82+
minimum[i] = std::min(minimum[i], float(it[c]));
83+
maximum[i] = std::max(maximum[i], float(it[c]));
84+
i++;
85+
}
3386
}
34-
if (! inp->close ())
87+
}
88+
89+
90+
void ImagePlaneData::getRange(float *minimum, float *maximum)
91+
{
92+
for (int i = 0; i < len; i++)
3593
{
36-
std::cerr << "Error closing " << imageFileName
37-
<< ", error = " << inp->geterror() << "\n";
38-
return;
94+
minimum[i] = FLT_MAX;
95+
maximum[i] = FLT_MIN;
3996
}
4097

41-
ready = LOADED;
98+
float missing[4] = { 0.0, 0.0, 0.0, 0.0 };
99+
OIIO::attribute ("missingcolor", OIIO::TypeDesc("float[4]"), &missing);
100+
101+
if (buffer.spec().format == OIIO::TypeDesc::FLOAT)
102+
getRange_impl<float> (this, minimum, maximum);
103+
else if (buffer.spec().format == OIIO::TypeDesc::HALF)
104+
getRange_impl<half> (this, minimum, maximum);
105+
else if (buffer.spec().format == OIIO::TypeDesc::UINT8)
106+
getRange_impl<unsigned char> (this, minimum, maximum);
107+
else if (buffer.spec().format == OIIO::TypeDesc::UINT16)
108+
getRange_impl<unsigned short> (this, minimum, maximum);
109+
42110
}
43111

44112

45113
void ImagePlaneData::generateGlTexture()
46114
{
115+
if (ready != LOADED)
116+
return;
117+
47118
glPixelStorei(GL_PACK_ALIGNMENT, 2);
48119
glPixelStorei(GL_UNPACK_ALIGNMENT, 2);
49120

@@ -67,5 +138,7 @@ void ImagePlaneData::generateGlTexture()
67138
&pixels[0]);
68139

69140
// std::cout << glGetError() << std::endl;
70-
141+
delete[] pixels;
142+
143+
ready = TEXTURE_GENERATED;
71144
}

src/imagePlane.h

Lines changed: 66 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
#include <vector>
44
#include <GL/glew.h>
55
#include <OpenImageIO/imageio.h>
6+
#include <OpenImageIO/imagebuf.h>
7+
#include <OpenImageIO/imagecache.h>
68

79
// #define PRECISION_FLOAT
810

@@ -19,65 +21,76 @@
1921
static int internalFormats[] = {0, GL_R16F, GL_RG16F, GL_RGB16F, GL_RGBA16F};
2022
#endif
2123

24+
25+
// Represent image data and properties of certain level of MIP
2226
struct ImagePlaneData
2327
{
24-
void load();
25-
void generateGlTexture();
26-
27-
std::string imageFileName;
28-
unsigned int subimage; // index for async loading
29-
unsigned int mip; // index for async loading
30-
31-
std::string name; // name of sub-image from metadata
32-
std::string groupName; // group name if exists
33-
std::string channels; // channels names after dot concatenated for corresponding group
34-
std::string format; // string representation of data type
35-
36-
// Data Window
37-
unsigned int imageWidth;
38-
unsigned int imageHeight;
39-
int imageOffsetX;
40-
int imageOffsetY;
41-
42-
// Display Window
43-
unsigned int windowWidth;
44-
unsigned int windowHeight;
45-
int windowOffsetX;
46-
int windowOffsetY;
47-
48-
bool windowMatchData; // is Data Window match Display Window
49-
float pixelAspect;
50-
51-
int begin; // index in oiio spec
52-
int len;
53-
precision *pixels; // fill deferred
54-
GLuint glTexture; // fill deferred
55-
56-
enum state
57-
{
58-
NOT_ISSUED,
59-
ISSUED,
60-
LOADING_STARTED,
61-
LOADED,
62-
TEXTURE_GENERATED,
63-
};
64-
65-
state ready = NOT_ISSUED;
66-
67-
~ImagePlaneData() { delete[] pixels;}
28+
void load();
29+
void generateGlTexture();
30+
void getRange(float*, float*);
31+
32+
std::string imageFileName;
33+
unsigned int subimage; // index for async loading
34+
unsigned int mip; // index for async loading
35+
36+
std::string name; // name of sub-image from metadata
37+
std::string groupName; // group name if exists
38+
std::string channels; // channels names after dot concatenated for corresponding group
39+
std::string format; // string representation of data type
40+
41+
std::string compression;
42+
int quality;
43+
int tile_width;
44+
int tile_height;
45+
46+
// Data Window
47+
unsigned int imageWidth;
48+
unsigned int imageHeight;
49+
int imageOffsetX;
50+
int imageOffsetY;
51+
52+
// Display Window
53+
unsigned int windowWidth;
54+
unsigned int windowHeight;
55+
int windowOffsetX;
56+
int windowOffsetY;
57+
58+
bool windowMatchData; // is Data Window match Display Window
59+
float pixelAspect;
60+
61+
int begin; // index in oiio spec
62+
int len;
63+
precision *pixels; // fill deferred
64+
GLuint glTexture; // fill deferred
65+
66+
enum state
67+
{
68+
NOT_ISSUED,
69+
ISSUED,
70+
LOADING_STARTED,
71+
LOADED,
72+
TEXTURE_GENERATED,
73+
};
74+
75+
state ready = NOT_ISSUED;
76+
77+
OIIO::ImageBuf buffer;
78+
std::shared_ptr<OIIO::ImageCache> cache;
6879
};
6980

81+
82+
// Represent individual channel 'group' within multichannel or multipart image
7083
struct ImagePlane
7184
{
72-
std::string name; // name of sub-image from metadata
73-
std::string groupName; // group name if exists
74-
std::string channels; // channels names after dot concatenated for corresponding group
75-
int nMIPs;
85+
std::string name; // name of sub-image from metadata
86+
std::string groupName; // group name if exists
87+
std::string channels; // channels names after dot concatenated for corresponding group
88+
int nMIPs;
7689

77-
float gainValues = 1.0;
78-
float offsetValues = 0.0;
79-
bool doOCIO = false; // guess from data type and channel naming
80-
bool checkNaN = true;
90+
float gainValues = 1.0;
91+
float offsetValues = 0.0;
92+
bool doOCIO = false; // guess from data type and channel naming
93+
bool checkNaN = true;
8194

82-
std::vector<ImagePlaneData> MIPs;
95+
std::vector<ImagePlaneData> MIPs; // Only one entry for non mip-mapped images
8396
};

0 commit comments

Comments
 (0)