[OpenEXR] update for OpenEXR-3.0 build config (#4624)

* [OpenEXR] update for OpenEXR-3.0 build config

Signed-off-by: Peter Hillman <peter@pedro.kiwi>
This commit is contained in:
metamerism 2020-11-10 16:02:22 +13:00 committed by GitHub
parent 8b10d4b705
commit 6195bf380e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 11 additions and 1057 deletions

View File

@ -18,4 +18,4 @@ FROM gcr.io/oss-fuzz-base/base-builder
RUN apt-get update && apt-get install -y make autoconf automake libtool zlib1g-dev
RUN git clone --depth 1 https://github.com/AcademySoftwareFoundation/openexr openexr
WORKDIR openexr
COPY build.sh *_fuzzer.cc *.h $SRC/
COPY build.sh $SRC/

View File

@ -28,30 +28,23 @@ CMAKE_SETTINGS=(
cmake $SRC/openexr ${CMAKE_SETTINGS[@]}
make -j$(nproc)
ar -qc $WORK/OpenEXR/libOpenexrUtils.a $(find $WORK/ -name "*.o")
INCLUDES=(
"-I $SRC"
"-I $SRC/openexr/OpenEXR/IlmImf"
"-I $SRC/openexr/OpenEXR/IlmImfUtil"
"-I $SRC/openexr/OpenEXR/exrenvmap"
"-I $SRC/openexr/IlmBase/Imath"
"-I $SRC/openexr/IlmBase/Iex"
"-I $SRC/openexr/IlmBase/Half"
"-I $WORK/OpenEXR/config"
"-I $WORK/IlmBase/config"
"-I $SRC/openexr/src/lib/OpenEXR"
"-I $SRC/openexr/src/lib/OpenEXRUtil"
"-I $WORK/cmake"
)
LIBS=(
"$WORK/OpenEXR/IlmImf/libIlmImf.a"
"$WORK/IlmBase/Iex/libIex.a"
"$WORK/IlmBase/Half/libHalf.a"
"$WORK/IlmBase/IlmThread/libIlmThread.a"
"$WORK/IlmBase/Imath/libImath.a"
"$WORK/OpenEXR/libOpenexrUtils.a"
"$WORK/src/lib/OpenEXRUtil/libOpenEXRUtil.a"
"$WORK/src/lib/OpenEXR/libOpenEXR.a"
"$WORK/src/lib/Iex/libIex.a"
"$WORK/src/lib/IexMath/libIexMath.a"
"$WORK/src/lib/IlmThread/libIlmThread.a"
"$WORK/_deps/imath-build/src/Imath/libImath*.a"
)
for fuzzer in $SRC/*_fuzzer.cc $SRC/openexr/OpenEXR/IlmImfFuzzTest/oss-fuzz/*_fuzzer.cc; do
for fuzzer in $SRC/openexr/src/test/OpenEXRFuzzTest/oss-fuzz/*_fuzzer.cc; do
fuzzer_basename=$(basename -s .cc $fuzzer)
$CXX $CXXFLAGS -std=c++11 -pthread ${INCLUDES[@]} $fuzzer $LIB_FUZZING_ENGINE ${LIBS[@]} -lz \
-o $OUT/$fuzzer_basename

View File

@ -1,81 +0,0 @@
// Copyright 2020 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// Adapter utility from fuzzer input to a temporary file, for fuzzing APIs that
// require a file instead of an input buffer.
#ifndef FUZZER_TEMP_FILE_H_
#define FUZZER_TEMP_FILE_H_
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
// Pure-C interface for creating and cleaning up temporary files.
static char *fuzzer_get_tmpfile(const uint8_t *data, size_t size) {
char *filename_buffer = strdup("/tmp/generate_temporary_file.XXXXXX");
if (!filename_buffer) {
perror("Failed to allocate file name buffer.");
abort();
}
const int file_descriptor = mkstemp(filename_buffer);
if (file_descriptor < 0) {
perror("Failed to make temporary file.");
abort();
}
FILE *file = fdopen(file_descriptor, "wb");
if (!file) {
perror("Failed to open file descriptor.");
close(file_descriptor);
abort();
}
const size_t bytes_written = fwrite(data, sizeof(uint8_t), size, file);
if (bytes_written != size) {
fclose(file);
fprintf(stderr, "Failed to write all bytes to file (%zu out of %zu)",
bytes_written, size);
abort();
}
fclose(file);
return filename_buffer;
}
static void fuzzer_release_tmpfile(char *filename) {
if (unlink(filename) != 0) {
perror("WARNING: Failed to delete temporary file.");
}
free(filename);
}
// C++ RAII object for creating temporary files.
#ifdef __cplusplus
class FuzzerTemporaryFile {
public:
FuzzerTemporaryFile(const uint8_t *data, size_t size)
: filename_(fuzzer_get_tmpfile(data, size)) {}
~FuzzerTemporaryFile() { fuzzer_release_tmpfile(filename_); }
const char *filename() const { return filename_; }
private:
char *filename_;
};
#endif
#endif // FUZZER_TEMP_FILE_H_

View File

@ -1,179 +0,0 @@
// Copyright 2020 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <vector>
#include <ImfArray.h>
#include <ImfChannelList.h>
#include <ImfDeepFrameBuffer.h>
#include <ImfDeepScanLineInputPart.h>
#include <ImfMultiPartInputFile.h>
#include <ImfNamespace.h>
#include <ImfStdIO.h>
#include <fuzzer/FuzzedDataProvider.h>
namespace IMF = OPENEXR_IMF_NAMESPACE;
using namespace IMF;
using IMATH_NAMESPACE::Box2i;
using IMATH_NAMESPACE::V2i;
namespace {
const int width = 90;
const int height = 80;
const int minX = 10;
const int minY = 11;
const Box2i dataWindow(V2i(minX, minY),
V2i(minX + width - 1, minY + height - 1));
const Box2i displayWindow(V2i(0, 0), V2i(minX + width * 2, minY + height * 2));
template <typename T>
static void readFile(T *inpart) {
const Header &fileHeader = inpart->header();
int channelCount = 0;
for (ChannelList::ConstIterator i = fileHeader.channels().begin();
i != fileHeader.channels().end(); ++i, ++channelCount) {
}
Array2D<unsigned int> localSampleCount;
localSampleCount.resizeErase(height, width);
Array<Array2D<void *> > data(channelCount);
for (int i = 0; i < channelCount; i++) data[i].resizeErase(height, width);
DeepFrameBuffer frameBuffer;
frameBuffer.insertSampleCountSlice(
Slice(IMF::UINT,
(char *)(&localSampleCount[0][0] - dataWindow.min.x -
dataWindow.min.y * width),
sizeof(unsigned int) * 1, sizeof(unsigned int) * width));
std::vector<int> read_channel(channelCount);
for (int i = 0; i < channelCount; i++) {
PixelType type = IMF::FLOAT;
std::stringstream ss;
ss << i;
std::string str = ss.str();
int sampleSize = sizeof(float);
int pointerSize = sizeof(char *);
frameBuffer.insert(
str, DeepSlice(type,
(char *)(&data[i][0][0] - dataWindow.min.x -
dataWindow.min.y * width),
pointerSize * 1, pointerSize * width, sampleSize));
}
inpart->setFrameBuffer(frameBuffer);
inpart->readPixelSampleCounts(dataWindow.min.y, dataWindow.max.y);
for (int i = 0; i < dataWindow.max.y - dataWindow.min.y + 1; i++) {
int y = i + dataWindow.min.y;
for (int j = 0; j < width; j++) {
for (int k = 0; k < channelCount; k++) {
data[k][i][j] = new float[localSampleCount[i][j]];
}
}
}
try {
inpart->readPixels(dataWindow.min.y, dataWindow.max.y);
} catch (...) {
}
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
for (int k = 0; k < channelCount; k++) {
delete[](float *) data[k][i][j];
}
}
}
}
static void readFileSingle(IStream& is, uint64_t width, uint64_t height) {
DeepScanLineInputFile *file = NULL;
try {
Header header(width, height);
file = new DeepScanLineInputFile(header, &is, EXR_VERSION, 0);
} catch (...) {
return;
}
try {
readFile(file);
} catch (...) {
}
delete file;
}
static void readFileMulti(IStream& is) {
MultiPartInputFile *file = NULL;
try {
file = new MultiPartInputFile(is, 0);
} catch (...) {
return;
}
for (int p = 0; p < file->parts(); p++) {
DeepScanLineInputPart *inpart = NULL;
try {
inpart = new DeepScanLineInputPart(*file, p);
} catch (...) {
continue;
}
try {
readFile(inpart);
} catch (...) {
}
delete inpart;
}
delete file;
}
} // namespace
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
if (size < 16) return 0;
FuzzedDataProvider stream(data, size);
uint64_t width = stream.ConsumeIntegral<uint64_t>();
uint64_t height = stream.ConsumeIntegral<uint64_t>();
std::vector<char> buffer = stream.ConsumeRemainingBytes<char>();
const std::string s(buffer.data(), buffer.size());
{
StdISStream is;
is.str(s);
readFileSingle(is, width, height);
}
{
StdISStream is;
is.str(s);
readFileMulti(is);
}
return 0;
}

View File

@ -1,180 +0,0 @@
// Copyright 2020 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <ImfArray.h>
#include <ImfChannelList.h>
#include <ImfDeepTiledInputFile.h>
#include <ImfDeepTiledInputPart.h>
#include <ImfTiledInputPart.h>
#include <ImfStdIO.h>
namespace IMF = OPENEXR_IMF_NAMESPACE;
using namespace IMF;
using IMATH_NAMESPACE::Box2i;
namespace {
template <typename T>
static void readFile(T *part) {
const Header &fileHeader = part->header();
Array2D<unsigned int> localSampleCount;
Box2i dataWindow = fileHeader.dataWindow();
int height = dataWindow.size().y + 1;
int width = dataWindow.size().x + 1;
localSampleCount.resizeErase(height, width);
int channelCount = 0;
for (ChannelList::ConstIterator i = fileHeader.channels().begin();
i != fileHeader.channels().end(); ++i, channelCount++) {
}
Array<Array2D<void *> > data(channelCount);
for (int i = 0; i < channelCount; i++) {
data[i].resizeErase(height, width);
}
DeepFrameBuffer frameBuffer;
int memOffset = dataWindow.min.x + dataWindow.min.y * width;
frameBuffer.insertSampleCountSlice(
Slice(IMF::UINT, (char *)(&localSampleCount[0][0] - memOffset),
sizeof(unsigned int) * 1, sizeof(unsigned int) * width));
for (int i = 0; i < channelCount; i++) {
std::stringstream ss;
ss << i;
std::string str = ss.str();
int sampleSize = sizeof(float);
int pointerSize = sizeof(char *);
frameBuffer.insert(
str, DeepSlice(IMF::FLOAT, (char *)(&data[i][0][0] - memOffset),
pointerSize * 1, pointerSize * width, sampleSize));
}
part->setFrameBuffer(frameBuffer);
for (int ly = 0; ly < part->numYLevels(); ly++) {
for (int lx = 0; lx < part->numXLevels(); lx++) {
Box2i dataWindowL = part->dataWindowForLevel(lx, ly);
part->readPixelSampleCounts(0, part->numXTiles(lx) - 1, 0,
part->numYTiles(ly) - 1, lx, ly);
for (int i = 0; i < part->numYTiles(ly); i++) {
for (int j = 0; j < part->numXTiles(lx); j++) {
Box2i box = part->dataWindowForTile(j, i, lx, ly);
for (int y = box.min.y; y <= box.max.y; y++)
for (int x = box.min.x; x <= box.max.x; x++) {
int dwy = y - dataWindowL.min.y;
int dwx = x - dataWindowL.min.x;
for (int k = 0; k < channelCount; k++) {
data[k][dwy][dwx] = new float[localSampleCount[dwy][dwx]];
}
}
}
}
try {
part->readTiles(0, part->numXTiles(lx) - 1, 0, part->numYTiles(ly) - 1,
lx, ly);
} catch (...) {
}
for (int i = 0; i < part->levelHeight(ly); i++) {
for (int j = 0; j < part->levelWidth(lx); j++) {
for (int k = 0; k < channelCount; k++) {
delete[](float *) data[k][i][j];
}
}
}
}
}
}
static void readFileSingle(IStream& is) {
DeepTiledInputFile *file;
try {
file = new DeepTiledInputFile(is, 8);
} catch (...) {
return;
}
try {
readFile(file);
} catch (...) {
}
delete file;
}
static void readFileMulti(IStream& is) {
MultiPartInputFile *file;
try {
file = new MultiPartInputFile(is, 8);
} catch (...) {
return;
}
for (int p = 0; p < file->parts(); p++) {
DeepTiledInputPart *part;
try {
part = new DeepTiledInputPart(*file, p);
} catch (...) {
continue;
}
try {
readFile(part);
} catch (...) {
}
delete part;
}
delete file;
}
} // namespace
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
const std::string s(reinterpret_cast<const char*>(data), size);
Header::setMaxImageSize(10000, 10000);
{
StdISStream is;
is.str(s);
readFileSingle(is);
}
{
StdISStream is;
is.str(s);
readFileMulti(is);
}
return 0;
}

View File

@ -1,116 +0,0 @@
// Copyright 2020 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <EnvmapImage.h>
#include <ImfEnvmap.h>
#include <ImfHeader.h>
#include <ImfStdIO.h>
#include <ImfMultiPartInputFile.h>
#include <blurImage.h>
#include <makeCubeMap.h>
#include <makeLatLongMap.h>
#include <exception>
#include <iostream>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <string>
#include <unistd.h>
#include "fuzzer_temp_file.h"
using namespace OPENEXR_IMF_NAMESPACE;
using namespace std;
static char *buf_to_file(const char *buf, size_t size) {
char *name = strdup("/tmp/fuzz-XXXXXX");
int fd = mkstemp(name);
if (fd < 0) {
perror("open");
exit(1);
}
size_t pos = 0;
while (pos < size) {
int nbytes = write(fd, &buf[pos], size - pos);
if (nbytes <= 0) {
perror("write");
exit(1);
}
pos += nbytes;
}
if (close(fd) != 0) {
perror("close");
exit(1);
}
return name;
}
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
//
// confirm file will take less than 2GiB to store entire image in memory
//
try {
StdISStream is;
std::string s(reinterpret_cast<const char*>(data), size);
is.str(s);
MultiPartInputFile inputFile(is);
Imath::Box2i dataWindow = inputFile.header(0).dataWindow();
ssize_t area = (static_cast<ssize_t>(dataWindow.max.x) + 1 - static_cast<ssize_t>(dataWindow.min.x) )
*(static_cast<ssize_t>(dataWindow.max.y) + 1 - static_cast<ssize_t>(dataWindow.min.y) );
if (area*8ll > 2048ll*1024ll*1024ll )
{
return 0;
}
}
catch (...) {
return 0;
}
FuzzerTemporaryFile tempFile(data, size);
const char *filename = tempFile.filename();
if (!filename)
return 0;
Envmap overrideInputType = NUM_ENVMAPTYPES;
LevelMode levelMode = ONE_LEVEL;
LevelRoundingMode roundingMode = ROUND_DOWN;
Compression compression = ZIP_COMPRESSION;
int mapWidth = 256;
int tileWidth = 64;
int tileHeight = 64;
int numSamples = 5;
float filterRadius = 1;
EnvmapImage image;
Header header;
RgbaChannels channels;
try {
readInputImage(filename, 0, 0, overrideInputType, false, image, header,
channels);
makeCubeMap(image, header, channels, "/dev/null", tileWidth, tileHeight,
levelMode, roundingMode, compression, mapWidth, filterRadius,
numSamples, false);
} catch (...) {
;
}
return 0;
}

View File

@ -1,176 +0,0 @@
// Copyright 2020 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "ImfNamespace.h"
#include <ImfBoxAttribute.h>
#include <ImfChannelListAttribute.h>
#include <ImfChromaticitiesAttribute.h>
#include <ImfCompressionAttribute.h>
#include <ImfDoubleAttribute.h>
#include <ImfEnvmapAttribute.h>
#include <ImfFloatAttribute.h>
#include <ImfHeader.h>
#include <ImfIntAttribute.h>
#include <ImfKeyCodeAttribute.h>
#include <ImfLineOrderAttribute.h>
#include <ImfMatrixAttribute.h>
#include <ImfMultiPartInputFile.h>
#include <ImfPreviewImageAttribute.h>
#include <ImfRationalAttribute.h>
#include <ImfStdIO.h>
#include <ImfStringAttribute.h>
#include <ImfStringVectorAttribute.h>
#include <ImfTileDescriptionAttribute.h>
#include <ImfTimeCodeAttribute.h>
#include <ImfVecAttribute.h>
#include <ImfVersion.h>
#include <iomanip>
#include <iostream>
using namespace OPENEXR_IMF_NAMESPACE;
using namespace std;
void dumpTimeCode(TimeCode tc) {
tc.hours();
tc.minutes();
tc.seconds();
tc.frame();
tc.dropFrame();
tc.colorFrame();
tc.fieldPhase();
tc.bgf0();
tc.bgf1();
tc.bgf2();
tc.userData();
}
void dumpChannelList(const ChannelList &cl) {
for (ChannelList::ConstIterator i = cl.begin(); i != cl.end(); ++i) {
i.name();
i.channel();
}
}
void dumpInfo(IStream &is) {
MultiPartInputFile in(is, 0);
int parts = in.parts();
getVersion(in.version());
getFlags(in.version());
for (int p = 0; p < parts; ++p) {
const Header &h = in.header(p);
if (parts != 1) {
in.partComplete(p);
}
for (Header::ConstIterator i = h.begin(); i != h.end(); ++i) {
const Attribute *a = &i.attribute();
i.name();
a->typeName();
if (const Box2iAttribute *ta = dynamic_cast<const Box2iAttribute *>(a)) {
ta->value();
}
else if (const Box2fAttribute *ta =
dynamic_cast<const Box2fAttribute *>(a)) {
ta->value();
} else if (const ChannelListAttribute *ta =
dynamic_cast<const ChannelListAttribute *>(a)) {
dumpChannelList(ta->value());
} else if (const ChromaticitiesAttribute *ta =
dynamic_cast<const ChromaticitiesAttribute *>(a)) {
ta->value();
} else if (const DoubleAttribute *ta =
dynamic_cast<const DoubleAttribute *>(a)) {
ta->value();
} else if (const FloatAttribute *ta =
dynamic_cast<const FloatAttribute *>(a)) {
ta->value();
} else if (const IntAttribute *ta =
dynamic_cast<const IntAttribute *>(a)) {
ta->value();
} else if (const KeyCodeAttribute *ta =
dynamic_cast<const KeyCodeAttribute *>(a)) {
ta->value().filmMfcCode();
ta->value().filmType();
ta->value().prefix();
ta->value().count();
ta->value().perfOffset();
ta->value().perfsPerFrame();
ta->value().perfsPerCount();
} else if (const M33fAttribute *ta =
dynamic_cast<const M33fAttribute *>(a)) {
ta->value();
} else if (const M44fAttribute *ta =
dynamic_cast<const M44fAttribute *>(a)) {
ta->value();
} else if (const PreviewImageAttribute *ta =
dynamic_cast<const PreviewImageAttribute *>(a)) {
ta->value().width();
ta->value().height();
} else if (const StringAttribute *ta =
dynamic_cast<const StringAttribute *>(a)) {
ta->value();
} else if (const StringVectorAttribute *ta =
dynamic_cast<const StringVectorAttribute *>(a)) {
for (StringVector::const_iterator i = ta->value().begin();
i != ta->value().end(); ++i) {
*i;
}
} else if (const RationalAttribute *ta =
dynamic_cast<const RationalAttribute *>(a)) {
ta->value();
} else if (const TileDescriptionAttribute *ta =
dynamic_cast<const TileDescriptionAttribute *>(a)) {
ta->value();
} else if (const TimeCodeAttribute *ta =
dynamic_cast<const TimeCodeAttribute *>(a)) {
dumpTimeCode(ta->value());
} else if (const V2iAttribute *ta =
dynamic_cast<const V2iAttribute *>(a)) {
ta->value();
} else if (const V2fAttribute *ta =
dynamic_cast<const V2fAttribute *>(a)) {
ta->value();
} else if (const V3iAttribute *ta =
dynamic_cast<const V3iAttribute *>(a)) {
ta->value();
} else if (const V3fAttribute *ta =
dynamic_cast<const V3fAttribute *>(a)) {
ta->value();
}
}
}
}
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
const std::string s(reinterpret_cast<const char *>(data), size);
StdISStream is;
is.str(s);
try {
dumpInfo(is);
} catch (...) {
;
}
return 0;
}

View File

@ -1,133 +0,0 @@
// Copyright 2020 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <vector>
#include <ImfArray.h>
#include <ImfInputPart.h>
#include <ImfMultiPartInputFile.h>
#include <ImfChannelList.h>
#include <ImfRgbaFile.h>
#include <ImfStdIO.h>
using namespace OPENEXR_IMF_INTERNAL_NAMESPACE;
using IMATH_NAMESPACE::Box2i;
using std::vector;
using std::max;
namespace {
static void readSingle(IStream& is) {
try {
RgbaInputFile in(is);
const Box2i &dw = in.dataWindow();
int w = dw.max.x - dw.min.x + 1;
int dx = dw.min.x;
if (w > (1 << 24)) return;
Array<Rgba> pixels(w);
in.setFrameBuffer(&pixels[-dx], 1, 0);
// read up to 10,000 scanlines from file
int step = max( 1 , (dw.max.y - dw.min.y + 1) / 10000);
for (int y = dw.min.y; y <= dw.max.y; y+=step) in.readPixels(y);
} catch (...) {
}
}
static void readMulti(IStream& is) {
MultiPartInputFile *file;
try {
file = new MultiPartInputFile(is);
} catch (...) {
return;
}
for (int p = 0; p < file->parts(); p++) {
InputPart *in;
try {
in = new InputPart(*file, p);
} catch (...) {
continue;
}
try {
const Box2i &dw = in->header().dataWindow();
int w = dw.max.x - dw.min.x + 1;
int dx = dw.min.x;
if (w > (1 << 24))
{
throw std::logic_error("ignoring - very wide datawindow\n");
}
FrameBuffer i;
//
// read all channels present (later channels will overwrite earlier ones)
vector<half> otherChannels(w);
const ChannelList& channelList = in->header().channels();
for (ChannelList::ConstIterator c = channelList.begin() ; c != channelList.end() ; ++c )
{
i.insert(c.name(),Slice(HALF, (char*)&otherChannels[-dx] , sizeof(half) , 0 ));
}
// always try to read RGBA even if not present in file
Array<Rgba> pixels(w);
i.insert("R", Slice(HALF, (char *)&(pixels[-dx].r), sizeof(Rgba), 0));
i.insert("G", Slice(HALF, (char *)&(pixels[-dx].g), sizeof(Rgba), 0));
i.insert("B", Slice(HALF, (char *)&(pixels[-dx].b), sizeof(Rgba), 0));
i.insert("A", Slice(HALF, (char *)&(pixels[-dx].a), sizeof(Rgba), 0));
in->setFrameBuffer(i);
// read up to 10,000 scanlines from file
int step = max( 1 , (dw.max.y - dw.min.y + 1) / 10000);
for (int y = dw.min.y; y <= dw.max.y; y+=step) in->readPixels(y);
} catch (...) {
}
delete in;
}
delete file;
}
} // namespace
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
const std::string s(reinterpret_cast<const char*>(data), size);
{
StdISStream is;
is.str(s);
readSingle(is);
}
{
StdISStream is;
is.str(s);
readMulti(is);
}
return 0;
}

View File

@ -1,174 +0,0 @@
// Copyright 2020 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <ImfArray.h>
#include <ImfTiledRgbaFile.h>
// Handle the case when the custom namespace is not exposed
#include <ImfChannelList.h>
#include <ImfMultiPartInputFile.h>
#include <ImfMultiPartOutputFile.h>
#include <ImfPartType.h>
#include <ImfTiledInputPart.h>
#include <ImfTiledOutputPart.h>
#include <OpenEXRConfig.h>
#include <ImfStdIO.h>
using namespace OPENEXR_IMF_INTERNAL_NAMESPACE;
using IMATH_NAMESPACE::Box2i;
namespace {
void readImageONE(TiledRgbaInputFile *in, int dwx, int dwy) {
try {
const Box2i &dw = in->dataWindow();
int w = dw.max.x - dw.min.x + 1;
int h = dw.max.y - dw.min.y + 1;
Array2D<Rgba> pixels(h, w);
in->setFrameBuffer(&pixels[-dwy][-dwx], 1, w);
in->readTiles(0, in->numXTiles() - 1, 0, in->numYTiles() - 1);
} catch (...) {
}
}
void readImageONE2(IStream& is) {
MultiPartInputFile *in;
try {
in = new MultiPartInputFile(is);
} catch (...) {
return;
}
TiledInputPart *inpart;
try {
for (int p = 0; p < in->parts(); p++) {
try {
inpart = new TiledInputPart(*in, p);
} catch (...) {
inpart = NULL;
continue;
}
const Box2i &dw = inpart->header().dataWindow();
int w = dw.max.x - dw.min.x + 1;
int h = dw.max.y - dw.min.y + 1;
int dwx = dw.min.x;
int dwy = dw.min.y;
Array2D<Rgba> pixels(h, w);
FrameBuffer i;
i.insert("R", Slice(HALF, (char *)&(pixels[-dwy][-dwx].r), sizeof(Rgba),
w * sizeof(Rgba)));
i.insert("G", Slice(HALF, (char *)&(pixels[-dwy][-dwx].g), sizeof(Rgba),
w * sizeof(Rgba)));
i.insert("B", Slice(HALF, (char *)&(pixels[-dwy][-dwx].b), sizeof(Rgba),
w * sizeof(Rgba)));
i.insert("A", Slice(HALF, (char *)&(pixels[-dwy][-dwx].a), sizeof(Rgba),
w * sizeof(Rgba)));
inpart->setFrameBuffer(i);
inpart->readTiles(0, inpart->numXTiles() - 1, 0, inpart->numYTiles() - 1);
delete inpart;
inpart = NULL;
}
} catch (...) {
delete inpart;
}
delete in;
}
void readImageMIP(TiledRgbaInputFile *in, int dwx, int dwy) {
try {
int numLevels = in->numLevels();
Array<Array2D<Rgba> > levels2(numLevels);
for (int level = 0; level < numLevels; ++level) {
int levelWidth = in->levelWidth(level);
int levelHeight = in->levelHeight(level);
levels2[level].resizeErase(levelHeight, levelWidth);
in->setFrameBuffer(&(levels2[level])[-dwy][-dwx], 1, levelWidth);
in->readTiles(0, in->numXTiles(level) - 1, 0, in->numYTiles(level) - 1,
level);
}
} catch (...) {
}
}
void readImageRIP(TiledRgbaInputFile *in, int dwx, int dwy) {
try {
int numXLevels = in->numXLevels();
int numYLevels = in->numYLevels();
Array2D<Array2D<Rgba> > levels2(numYLevels, numXLevels);
for (int ylevel = 0; ylevel < numYLevels; ++ylevel) {
for (int xlevel = 0; xlevel < numXLevels; ++xlevel) {
int levelWidth = in->levelWidth(xlevel);
int levelHeight = in->levelHeight(ylevel);
levels2[ylevel][xlevel].resizeErase(levelHeight, levelWidth);
in->setFrameBuffer(&(levels2[ylevel][xlevel])[-dwy][-dwx], 1,
levelWidth);
in->readTiles(0, in->numXTiles(xlevel) - 1, 0,
in->numYTiles(ylevel) - 1, xlevel, ylevel);
}
}
} catch (...) {
}
}
} // namespace
static void fuzzImage(IStream& is) {
Header::setMaxImageSize(10000, 10000);
Header::setMaxTileSize(10000, 10000);
TiledRgbaInputFile *in;
try {
in = new TiledRgbaInputFile(is);
} catch (...) {
return;
}
const Box2i &dw = in->dataWindow();
int dwx = dw.min.x;
int dwy = dw.min.y;
readImageMIP(in, dwx, dwy);
readImageRIP(in, dwx, dwy);
readImageONE(in, dwx, dwy);
readImageONE2(is);
delete in;
}
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
const std::string s(reinterpret_cast<const char*>(data), size);
StdISStream is;
is.str(s);
fuzzImage(is);
return 0;
}