// 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 #include #include #include #include #include #include #include #include #include #include #include #include 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 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 localSampleCount; localSampleCount.resizeErase(height, width); Array > 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 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 height = stream.ConsumeIntegral(); std::vector buffer = stream.ConsumeRemainingBytes(); 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; }