AcademySoftwareFoundation / AcademySoftwareFoundation/OpenImageIO
[BUG] Internal "contiguize" operation is incorrect
- Dominant language
- C++
- Stars
- 2.4k
- Forks
- 698
- Avg merge
- 3d 9h
- Merged PRs (30d)
- 48
Description
**Describe the bug**
The internal "contiguize" operation used when shifting between different TypeDescs is broken if the formats also differ in number of channels. E.g. Taking data from a TypeDesc::FLOAT,1-channel format to a TypeDesc::UINT16,3-channel format.
**To Reproduce**
Steps to reproduce the behavior:
```c++
/* A simple 8x4 FLOAT, 1-channel image */
const int width = 8;
const int height = 4;
float data[] = {
0.0, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.0,
0.0, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.0,
0.0, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.0,
0.0, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.0,
};
/* In memory format */
const int mem_channels = 1;
stride_t mem_xstride = sizeof(float) * mem_channels;
stride_t mem_ystride = width * mem_xstride;
uchar * mem_start = reinterpret_cast(data);
ImageSpec mem_spec(width, height, mem_channels, TypeDesc::FLOAT);
/* We always write using a negative y-stride so ensure we start at the end of the data. */
mem_start = mem_start + ((stride_t(height) - 1) * mem_ystride);
ImageBuf orig_buf(mem_spec, mem_start, mem_xstride, -mem_ystride, AutoStride);
/* Write out as a 8x4 UINT16, 3-channel image... */
ImageSpec file_spec(width, height, 3, TypeDesc::UINT16);
unique_ptr out = ImageOutput::create("tif");
if (!out) {
return false;
}
if (out->open("t:/oiio_16bit_debug.tiff", file_spec)) {
orig_buf.write(out.get());
out->close();
}
```
**Expected behavior**
Per the above, there's only 2 values in the initial data set: 0.0f and 0.5f. Saving the file out should still be 2 color tones.
**Evidence**
Attached is the resulting .tiff but I'll embed an enlarged image here that shows the color-shift that results from incorrectly assigning the pixel data in the contiguize operation:

[oiio_16bit_debug.zip](https://github.com/OpenImageIO/oiio/files/12424426/oiio_16bit_debug.zip)
Contributor guide
Research direction
Start by locating the internal "contiguize" operation used when shifting between different TypeDescs, then reproduce the issue with the provided 8x4 FLOAT, 1-channel input and UINT16, 3-channel output example. Done means writing the image preserves the two input color tones without the reported color shift.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp
- Domain
- computer-graphics
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100