diff --git a/src/cmake/testing.cmake b/src/cmake/testing.cmake index 06d4dfc2d0..ed1e678dd8 100644 --- a/src/cmake/testing.cmake +++ b/src/cmake/testing.cmake @@ -332,6 +332,9 @@ macro (oiio_add_all_tests) oiio_add_tests (sgi ENABLEVAR ENABLE_SGI IMAGEDIR oiio-images) + oiio_add_tests (softimage + ENABLEVAR ENABLE_SOFTIMAGE + IMAGEDIR oiio-images/softimage) oiio_add_tests (targa ENABLEVAR ENABLE_TARGA IMAGEDIR oiio-images) diff --git a/src/softimage.imageio/softimageinput.cpp b/src/softimage.imageio/softimageinput.cpp index 5fe46a2269..4a5584eb04 100644 --- a/src/softimage.imageio/softimageinput.cpp +++ b/src/softimage.imageio/softimageinput.cpp @@ -42,6 +42,9 @@ class SoftimageInput final : public ImageInput { read_pixels_mixed_run_length(const softimage_pvt::ChannelPacket& curPacket, void* data); + // Name for encoding + const char* encoding_name(int encoding); + FILE* m_fd; softimage_pvt::PicFileHeader m_pic_header; std::vector m_channel_packets; @@ -108,6 +111,7 @@ SoftimageInput::open(const std::string& name, ImageSpec& spec) // Get the ChannelPackets ChannelPacket curPacket; int nchannels = 0; + std::vector encodings; do { // Read the next packet into curPacket and store it off if (fread(&curPacket, 1, sizeof(ChannelPacket), m_fd) @@ -120,6 +124,7 @@ SoftimageInput::open(const std::string& name, ImageSpec& spec) // Add the number of channels in this packet to nchannels nchannels += curPacket.channels().size(); + encodings.push_back(encoding_name(m_channel_packets.back().type)); } while (curPacket.chained); // Get the depth per pixel per channel @@ -132,6 +137,8 @@ SoftimageInput::open(const std::string& name, ImageSpec& spec) chanType); m_spec.attribute("BitsPerSample", (int)curPacket.size); + m_spec.attribute("softimage:compression", Strutil::join(encodings, ",")); + if (m_pic_header.comment[0] != 0) { char comment[80]; Strutil::safe_strcpy(comment, m_pic_header.comment, 80); @@ -225,35 +232,39 @@ SoftimageInput::close() -inline bool +const char* +SoftimageInput::encoding_name(int encoding) +{ + switch (encoding & 0x3) { + case UNCOMPRESSED: return "none"; + case PURE_RUN_LENGTH: return "rle"; + case MIXED_RUN_LENGTH: return "mixed-rle"; + default: return "unknown"; + } +} + + + +bool SoftimageInput::read_next_scanline(void* data) { // Each scanline is stored using one or more channel packets. // We go through each of those to pull the data for (auto& cp : m_channel_packets) { - if (cp.type & UNCOMPRESSED) { - if (!read_pixels_uncompressed(cp, data)) { - errorfmt("Failed to read uncompressed pixel data from \"{}\"", - m_filename); - close(); - return false; - } - } else if (cp.type & PURE_RUN_LENGTH) { - if (!read_pixels_pure_run_length(cp, data)) { - errorfmt( - "Failed to read pure run length encoded pixel data from \"{}\"", - m_filename); - close(); - return false; - } - } else if (cp.type & MIXED_RUN_LENGTH) { - if (!read_pixels_mixed_run_length(cp, data)) { - errorfmt( - "Failed to read mixed run length encoded pixel data from \"{}\"", - m_filename); - close(); - return false; - } + bool ok = false; + int type = int(cp.type) & 0x3; + if (type == UNCOMPRESSED) { + ok = read_pixels_uncompressed(cp, data); + } else if (type == PURE_RUN_LENGTH) { + ok = read_pixels_pure_run_length(cp, data); + } else if (type == MIXED_RUN_LENGTH) { + ok = read_pixels_mixed_run_length(cp, data); + } + if (!ok) { + errorfmt("Failed to read channel packed type {:d} from \"{}\"", + int(cp.type), m_filename); + close(); + return false; } } return true; @@ -261,7 +272,7 @@ SoftimageInput::read_next_scanline(void* data) -inline bool +bool SoftimageInput::read_pixels_uncompressed( const softimage_pvt::ChannelPacket& curPacket, void* data) { @@ -304,7 +315,7 @@ SoftimageInput::read_pixels_uncompressed( -inline bool +bool SoftimageInput::read_pixels_pure_run_length( const softimage_pvt::ChannelPacket& curPacket, void* data) { @@ -365,7 +376,7 @@ SoftimageInput::read_pixels_pure_run_length( -inline bool +bool SoftimageInput::read_pixels_mixed_run_length( const softimage_pvt::ChannelPacket& curPacket, void* data) { diff --git a/testsuite/softimage/ref/out.txt b/testsuite/softimage/ref/out.txt new file mode 100644 index 0000000000..7050b67d84 --- /dev/null +++ b/testsuite/softimage/ref/out.txt @@ -0,0 +1,32 @@ +Reading ../oiio-images/softimage/A4.pic +../oiio-images/softimage/A4.pic : 64 x 64, 4 channel, uint8 softimage + SHA-1: 6A9FFED68FE36B0DA8544C1A3CBD671F662F8142 + channel list: R, G, B, A + BitsPerSample: 8 + ImageDescription: "Created by Houdini" + softimage:compression: "mixed-rle,mixed-rle" + Stats Min: 0 0 0 0 (of 255) + Stats Max: 255 255 255 255 (of 255) + Stats Avg: 2.29 2.29 2.29 2.29 (of 255) + Stats StdDev: 21.26 21.26 21.26 21.26 (of 255) + Stats NanCount: 0 0 0 0 + Stats InfCount: 0 0 0 0 + Stats FiniteCount: 4096 4096 4096 4096 + Constant: No + Monochrome: Yes +Reading ../oiio-images/softimage/astone64.pic +../oiio-images/softimage/astone64.pic : 64 x 64, 3 channel, uint8 softimage + SHA-1: 0FD57F8BBD941261055C65A64BBA294D9C21664F + channel list: R, G, B + BitsPerSample: 8 + ImageDescription: "ImageFX SoftImage Saver (Amiga)" + softimage:compression: "none" + Stats Min: 26 30 0 (of 255) + Stats Max: 255 255 174 (of 255) + Stats Avg: 154.83 158.82 68.19 (of 255) + Stats StdDev: 37.89 37.86 29.05 (of 255) + Stats NanCount: 0 0 0 + Stats InfCount: 0 0 0 + Stats FiniteCount: 4096 4096 4096 + Constant: No + Monochrome: No diff --git a/testsuite/softimage/run.py b/testsuite/softimage/run.py new file mode 100755 index 0000000000..c6d991b1f8 --- /dev/null +++ b/testsuite/softimage/run.py @@ -0,0 +1,10 @@ +#!/usr/bin/env python + +# Copyright Contributors to the OpenImageIO project. +# SPDX-License-Identifier: Apache-2.0 +# https://github.com/AcademySoftwareFoundation/OpenImageIO + +files = [ "A4.pic", "astone64.pic" ] +for f in files: + command += info_command (OIIO_TESTSUITE_IMAGEDIR + "/" + f, extraargs="--stats") +