mirror of https://github.com/google/oss-fuzz.git
175 lines
4.7 KiB
C++
175 lines
4.7 KiB
C++
// 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;
|
|
}
|