diff --git a/CMakeLists.txt b/CMakeLists.txt index e2709046..f56da3ec 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,6 @@ cmake_minimum_required(VERSION 3.12) -project(SAIL VERSION 0.9.0 +project(SAIL VERSION 0.9.1 DESCRIPTION "Squirrel Abstract Image Library" LANGUAGES C CXX) diff --git a/FORMATS.md b/FORMATS.md index fbd206a0..cfd4192b 100644 --- a/FORMATS.md +++ b/FORMATS.md @@ -239,6 +239,21 @@ 11 + PNM + + Grayscale: 1-bit, 8-bit, 16-bit. + Indexed: 1-bit, 8-bit. + RGB: 24-bit, 48-bit. +

+ Content: Static. + + - + Unsupported + - + - + + + 12 PSD Grayscale: 8-bit, 16-bit. @@ -265,7 +280,7 @@ - - 12 + 13 QOI RGB: 24-bit. @@ -284,7 +299,7 @@ - - 13 + 14 SVG Bit depth: 32-bit. @@ -303,7 +318,7 @@ resvg or nanosvg - 14 + 15 TGA Grayscale: 8-bit. @@ -319,7 +334,7 @@ - - 15 + 16 TIFF Bit depth: 1-bit, 2-bit, 4-bit, 8-bit, 16-bit, 24-bit, 32-bit, 48-bit, 64-bit. @@ -340,7 +355,7 @@ libtiff - 16 + 17 WAL Indexed: 8-bit. @@ -353,7 +368,7 @@ - - 17 + 18 WEBP Bit depth: 24-bit, 32-bit. @@ -366,7 +381,7 @@ libwebp - 18 + 19 XBM Bit depth: 1-bit. diff --git a/README.md b/README.md index 11f997c7..49ca0115 100644 --- a/README.md +++ b/README.md @@ -79,13 +79,14 @@ images with the help of [ksquirrel-libs](FAQ.md#how-old-is-sail), the predecesso | 8 | [JPEG XL](https://wikipedia.org/wiki/JPEG_XL) | R | libjxl | | 9 | [PCX](https://wikipedia.org/wiki/PCX) | R | | | 10 | [PNG](https://wikipedia.org/wiki/Portable_Network_Graphics) | RW | libpng | -| 11 | [PSD](https://en.wikipedia.org/wiki/Adobe_Photoshop#File_format) | R | | -| 12 | [QOI](http://qoiformat.org) | RW | | -| 13 | [SVG](https://wikipedia.org/wiki/Scalable_Vector_Graphics) | R | resvg | -| 14 | [TGA](https://wikipedia.org/wiki/Truevision_TGA) | R | | -| 15 | [TIFF](https://wikipedia.org/wiki/TIFF) | RW | libtiff | | .. | ... | | | -| 17 | [WEBP](https://wikipedia.org/wiki/WebP) | R | libwebp | +| 12 | [PSD](https://en.wikipedia.org/wiki/Adobe_Photoshop#File_format) | R | | +| 13 | [QOI](http://qoiformat.org) | RW | | +| 14 | [SVG](https://wikipedia.org/wiki/Scalable_Vector_Graphics) | R | resvg | +| 15 | [TGA](https://wikipedia.org/wiki/Truevision_TGA) | R | | +| 16 | [TIFF](https://wikipedia.org/wiki/TIFF) | RW | libtiff | +| .. | ... | | | +| 18 | [WEBP](https://wikipedia.org/wiki/WebP) | R | libwebp | | .. | ... | | | See the full list [here](FORMATS.md). Work to add more image formats is ongoing. diff --git a/src/sail-codecs/CMakeLists.txt b/src/sail-codecs/CMakeLists.txt index 2996212c..457f3a69 100644 --- a/src/sail-codecs/CMakeLists.txt +++ b/src/sail-codecs/CMakeLists.txt @@ -7,7 +7,7 @@ add_subdirectory(common/bmp) set(HIGHEST_PRIORITY_CODECS gif jpeg png tiff) set(HIGH_PRIORITY_CODECS bmp svg) set(MEDIUM_PRIORITY_CODECS avif jpeg2000 jpegxl webp) -set(LOW_PRIORITY_CODECS ico pcx psd qoi tga) +set(LOW_PRIORITY_CODECS ico pcx pnm psd qoi tga) set(LOWEST_PRIORITY_CODECS wal xbm) set(CODECS ${HIGHEST_PRIORITY_CODECS} diff --git a/src/sail-codecs/pnm/CMakeLists.txt b/src/sail-codecs/pnm/CMakeLists.txt new file mode 100644 index 00000000..632a0f97 --- /dev/null +++ b/src/sail-codecs/pnm/CMakeLists.txt @@ -0,0 +1,3 @@ +# Common codec configuration +# +sail_codec(NAME pnm SOURCES helpers.h helpers.c pnm.c ICON pnm.png) diff --git a/src/sail-codecs/pnm/helpers.c b/src/sail-codecs/pnm/helpers.c new file mode 100644 index 00000000..8148514a --- /dev/null +++ b/src/sail-codecs/pnm/helpers.c @@ -0,0 +1,169 @@ +/* This file is part of SAIL (https://github.com/HappySeaFox/sail) + + Copyright (c) 2023 Dmitry Baryshev + + The MIT License + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. +*/ + +#include +#include +#include +#include + +#include + +#include "helpers.h" + +sail_status_t pnm_private_skip_to_letters_numbers_force_read(struct sail_io *io, char *first_char) { + + char c; + + do { + SAIL_TRY(io->strict_read(io->stream, &c, 1)); + + if (c == '#') { + do { + SAIL_TRY(io->strict_read(io->stream, &c, 1)); + } while(c != '\n'); + } + } while (!isalnum(c)); + + *first_char = c; + + return SAIL_OK; +} + +sail_status_t pnm_private_skip_to_letters_numbers(struct sail_io *io, char starting_char, char *first_char) { + + if (isalnum(starting_char)) { + *first_char = starting_char; + return SAIL_OK; + } + + SAIL_TRY(pnm_private_skip_to_letters_numbers_force_read(io, first_char)); + + return SAIL_OK; +} + +sail_status_t pnm_private_read_word(struct sail_io *io, char *str, size_t str_size) { + + if (str_size < 2) { + SAIL_LOG_AND_RETURN(SAIL_ERROR_INVALID_ARGUMENT); + } + + char first_char; + SAIL_TRY(pnm_private_skip_to_letters_numbers(io, SAIL_PNM_INVALID_STARTING_CHAR, &first_char)); + + unsigned i = 0; + char c = first_char; + + bool eof; + SAIL_TRY(io->eof(io->stream, &eof)); + + sail_status_t saved_status = SAIL_OK; + + while (isalnum(c) && i < str_size - 1 && !eof) { + *(str + i++) = c; + SAIL_TRY_OR_EXECUTE(io->strict_read(io->stream, &c, 1), + /* on error */ saved_status = __sail_status); + SAIL_TRY(io->eof(io->stream, &eof)); + + if (saved_status != SAIL_OK && !eof) { + return saved_status; + } + } + + /* The buffer is full but no word delimiter found. */ + if (i == str_size - 1 && !eof) { + SAIL_LOG_ERROR("PNM: No word delimiter found"); + SAIL_LOG_AND_RETURN(SAIL_ERROR_BROKEN_IMAGE); + } + + *(str + i) = '\0'; + + return SAIL_OK; +} + +sail_status_t pnm_private_read_pixels(struct sail_io *io, struct sail_image *image, unsigned channels, unsigned bpc, double multiplier_to_full_range) { + + for (unsigned row = 0; row < image->height; row++) { + uint8_t *scan8 = sail_scan_line(image, row); + uint16_t *scan16 = sail_scan_line(image, row); + + for (unsigned column = 0; column < image->width; column++) { + for(unsigned channel = 0; channel < channels; channel++) { + char buffer[8]; + SAIL_TRY(pnm_private_read_word(io, buffer, sizeof(buffer))); + + unsigned value; + #ifdef _MSC_VER + if (sscanf_s(buffer, "%u", &value) != 1) { + #else + if (sscanf(buffer, "%u", &value) != 1) { + #endif + SAIL_LOG_ERROR("PNM: Failed to read color value"); + SAIL_LOG_AND_RETURN(SAIL_ERROR_BROKEN_IMAGE); + } + + if (SAIL_LIKELY(bpc == 8)) { + *scan8++ = (uint8_t)(value * multiplier_to_full_range); + } else { + *scan16++ = (uint16_t)(value * multiplier_to_full_range); + } + } + } + } + + return SAIL_OK; +} + +enum SailPixelFormat pnm_private_rgb_sail_pixel_format(enum SailPnmVersion pnm_version, unsigned bpc) { + + switch (pnm_version) { + case SAIL_PNM_VERSION_P1: + case SAIL_PNM_VERSION_P4: return SAIL_PIXEL_FORMAT_BPP1_INDEXED; + + case SAIL_PNM_VERSION_P2: + case SAIL_PNM_VERSION_P5: { + switch (bpc) { + case 8: return SAIL_PIXEL_FORMAT_BPP8_GRAYSCALE; + case 16: return SAIL_PIXEL_FORMAT_BPP16_GRAYSCALE; + + default: return SAIL_PIXEL_FORMAT_UNKNOWN; + } + } + + case SAIL_PNM_VERSION_P3: + case SAIL_PNM_VERSION_P6: { + switch (bpc) { + case 8: return SAIL_PIXEL_FORMAT_BPP24_RGB; + case 16: return SAIL_PIXEL_FORMAT_BPP48_RGB; + + default: return SAIL_PIXEL_FORMAT_UNKNOWN; + } + } + + default: { + return SAIL_PIXEL_FORMAT_UNKNOWN; + } + } +} + diff --git a/src/sail-codecs/pnm/helpers.h b/src/sail-codecs/pnm/helpers.h new file mode 100644 index 00000000..dcec56e9 --- /dev/null +++ b/src/sail-codecs/pnm/helpers.h @@ -0,0 +1,59 @@ +/* This file is part of SAIL (https://github.com/HappySeaFox/sail) + + Copyright (c) 2023 Dmitry Baryshev + + The MIT License + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. +*/ + +#ifndef SAIL_PNM_HELPERS_H +#define SAIL_PNM_HELPERS_H + +#include /* size_t */ + +#include +#include +#include + +struct sail_image; +struct sail_io; + +enum SailPnmVersion { + SAIL_PNM_VERSION_P1, + SAIL_PNM_VERSION_P2, + SAIL_PNM_VERSION_P3, + SAIL_PNM_VERSION_P4, + SAIL_PNM_VERSION_P5, + SAIL_PNM_VERSION_P6, +}; + +static const char SAIL_PNM_INVALID_STARTING_CHAR = '\0'; + +SAIL_HIDDEN sail_status_t pnm_private_skip_to_letters_numbers_force_read(struct sail_io *io, char *first_char); + +SAIL_HIDDEN sail_status_t pnm_private_skip_to_letters_numbers(struct sail_io *io, char starting_char, char *first_char); + +SAIL_HIDDEN sail_status_t pnm_private_read_word(struct sail_io *io, char *str, size_t str_size); + +SAIL_HIDDEN sail_status_t pnm_private_read_pixels(struct sail_io *io, struct sail_image *image, unsigned channels, unsigned bpc, double multiplier_to_full_range); + +SAIL_HIDDEN enum SailPixelFormat pnm_private_rgb_sail_pixel_format(enum SailPnmVersion pnm_version, unsigned bpc); + +#endif diff --git a/src/sail-codecs/pnm/pnm.c b/src/sail-codecs/pnm/pnm.c new file mode 100644 index 00000000..886cf459 --- /dev/null +++ b/src/sail-codecs/pnm/pnm.c @@ -0,0 +1,331 @@ +/* This file is part of SAIL (https://github.com/HappySeaFox/sail) + + Copyright (c) 2023 Dmitry Baryshev + + The MIT License + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. +*/ + +#include +#include +#include +#include +#include + +#include + +#include "helpers.h" + +static const uint8_t SAIL_PNM_MONO_PALETTE[] = { 255, 255, 255, 0, 0, 0 }; + +/* + * Codec-specific state. + */ +struct pnm_state { + struct sail_io *io; + const struct sail_load_options *load_options; + const struct sail_save_options *save_options; + + bool frame_loaded; + enum SailPnmVersion version; + double multiplier_to_full_range; + unsigned bpc; +}; + +static sail_status_t alloc_pnm_state(struct sail_io *io, + const struct sail_load_options *load_options, + const struct sail_save_options *save_options, + struct pnm_state **pnm_state) { + + void *ptr; + SAIL_TRY(sail_malloc(sizeof(struct pnm_state), &ptr)); + *pnm_state = ptr; + + **pnm_state = (struct pnm_state) { + .io = io, + .load_options = load_options, + .save_options = save_options, + + .frame_loaded = false, + + .multiplier_to_full_range = 0, + .bpc = 0, + }; + + return SAIL_OK; +} + +static void destroy_pnm_state(struct pnm_state *pnm_state) { + + if (pnm_state == NULL) { + return; + } + + sail_free(pnm_state); +} + +/* + * Decoding functions. + */ + +SAIL_EXPORT sail_status_t sail_codec_load_init_v8_pnm(struct sail_io *io, const struct sail_load_options *load_options, void **state) { + + *state = NULL; + + /* Allocate a new state. */ + struct pnm_state *pnm_state; + SAIL_TRY(alloc_pnm_state(io, load_options, NULL, &pnm_state)); + *state = pnm_state; + + /* Init decoder. */ + char str[8]; + SAIL_TRY(pnm_private_read_word(pnm_state->io, str, sizeof(str))); + + const char pnm = str[1]; + + SAIL_LOG_TRACE("PNM: Version '%c'", pnm); + + switch (pnm) { + case '1': pnm_state->version = SAIL_PNM_VERSION_P1; break; + case '2': pnm_state->version = SAIL_PNM_VERSION_P2; break; + case '3': pnm_state->version = SAIL_PNM_VERSION_P3; break; + case '4': pnm_state->version = SAIL_PNM_VERSION_P4; break; + case '5': pnm_state->version = SAIL_PNM_VERSION_P5; break; + case '6': pnm_state->version = SAIL_PNM_VERSION_P6; break; + + default: { + SAIL_LOG_ERROR("PNM: Unsupported version '%c'", pnm); + SAIL_LOG_AND_RETURN(SAIL_ERROR_UNSUPPORTED_FORMAT); + } + } + + return SAIL_OK; +} + +SAIL_EXPORT sail_status_t sail_codec_load_seek_next_frame_v8_pnm(void *state, struct sail_image **image) { + + struct pnm_state *pnm_state = state; + + if (pnm_state->frame_loaded) { + SAIL_LOG_AND_RETURN(SAIL_ERROR_NO_MORE_FRAMES); + } + + pnm_state->frame_loaded = true; + + char buffer[32]; + + /* Dimensions. */ + unsigned w; + SAIL_TRY(pnm_private_read_word(pnm_state->io, buffer, sizeof(buffer))); + +#ifdef _MSC_VER + if (sscanf_s(buffer, "%u", &w) != 1) { +#else + if (sscanf(buffer, "%u", &w) != 1) { +#endif + SAIL_LOG_ERROR("PNM: Failed to read image dimensions"); + SAIL_LOG_AND_RETURN(SAIL_ERROR_BROKEN_IMAGE); + } + + unsigned h; + SAIL_TRY(pnm_private_read_word(pnm_state->io, buffer, sizeof(buffer))); + +#ifdef _MSC_VER + if (sscanf_s(buffer, "%u", &h) != 1) { +#else + if (sscanf(buffer, "%u", &h) != 1) { +#endif + SAIL_LOG_ERROR("PNM: Failed to read image dimensions"); + SAIL_LOG_AND_RETURN(SAIL_ERROR_BROKEN_IMAGE); + } + + /* Maximum color. */ + if (pnm_state->version == SAIL_PNM_VERSION_P2 || + pnm_state->version == SAIL_PNM_VERSION_P3 || + pnm_state->version == SAIL_PNM_VERSION_P5 || + pnm_state->version == SAIL_PNM_VERSION_P6) { + + SAIL_TRY(pnm_private_read_word(pnm_state->io, buffer, sizeof(buffer))); + + unsigned max_color; +#ifdef _MSC_VER + if (sscanf_s(buffer, "%u", &max_color) != 1) { +#else + if (sscanf(buffer, "%u", &max_color) != 1) { +#endif + SAIL_LOG_ERROR("PNM: Failed to read maximum color value"); + SAIL_LOG_AND_RETURN(SAIL_ERROR_BROKEN_IMAGE); + } + + if (max_color <= 255) { + pnm_state->bpc = 8; + pnm_state->multiplier_to_full_range = 255.0 / max_color; + } else if (max_color <= 65535) { + pnm_state->bpc = 16; + pnm_state->multiplier_to_full_range = 65535.0 / max_color; + } else { + SAIL_LOG_ERROR("PNM: BPP more than 16 is not supported"); + SAIL_LOG_AND_RETURN(SAIL_ERROR_UNSUPPORTED_FORMAT); + } + + SAIL_LOG_TRACE("PNM: Max color(%u), scale(%.1f)", max_color, pnm_state->multiplier_to_full_range); + } else { + pnm_state->multiplier_to_full_range = 1; + pnm_state->bpc = 1; + } + + enum SailPixelFormat pixel_format = pnm_private_rgb_sail_pixel_format(pnm_state->version, pnm_state->bpc); + + if (pixel_format == SAIL_PIXEL_FORMAT_UNKNOWN) { + SAIL_LOG_ERROR("PNM: Unsupported pixel format"); + SAIL_LOG_AND_RETURN(SAIL_ERROR_UNSUPPORTED_PIXEL_FORMAT); + } + + struct sail_image *image_local; + SAIL_TRY(sail_alloc_image(&image_local)); + + if (pnm_state->load_options->options & SAIL_OPTION_SOURCE_IMAGE) { + SAIL_TRY_OR_CLEANUP(sail_alloc_source_image(&image_local->source_image), + /* cleanup */ sail_destroy_image(image_local)); + + image_local->source_image->pixel_format = pixel_format; + image_local->source_image->compression = SAIL_COMPRESSION_NONE; + } + + image_local->width = w; + image_local->height = h; + image_local->pixel_format = pixel_format; + image_local->delay = -1; + image_local->bytes_per_line = sail_bytes_per_line(image_local->width, image_local->pixel_format); + + if (pixel_format == SAIL_PIXEL_FORMAT_BPP1_INDEXED) { + SAIL_TRY_OR_CLEANUP(sail_alloc_palette_for_data(SAIL_PIXEL_FORMAT_BPP24_RGB, 2, &image_local->palette), + /* cleanup */ sail_destroy_image(image_local)); + + memcpy(image_local->palette->data, SAIL_PNM_MONO_PALETTE, 6); + } + + *image = image_local; + + return SAIL_OK; +} + +SAIL_EXPORT sail_status_t sail_codec_load_frame_v8_pnm(void *state, struct sail_image *image) { + + const struct pnm_state *pnm_state = state; + + switch (pnm_state->version) { + case SAIL_PNM_VERSION_P1: { + for (unsigned row = 0; row < image->height; row++) { + uint8_t *scan = sail_scan_line(image, row); + unsigned shift = 8; + + for (unsigned column = 0; column < image->width; column++) { + char first_char; + SAIL_TRY(pnm_private_skip_to_letters_numbers_force_read(pnm_state->io, &first_char)); + + const unsigned value = first_char - '0'; + + if (value != 0 && value != 1) { + SAIL_LOG_ERROR("PNM: Unexpected character '%c'", first_char); + SAIL_LOG_AND_RETURN(SAIL_ERROR_BROKEN_IMAGE); + } + + if (shift == 8) { + *scan = 0; + } + + *scan |= (value << --shift); + + if (shift == 0) { + scan++; + shift = 8; + } + } + } + break; + } + case SAIL_PNM_VERSION_P2: { + SAIL_TRY(pnm_private_read_pixels(pnm_state->io, image, 1, pnm_state->bpc, pnm_state->multiplier_to_full_range)); + break; + } + case SAIL_PNM_VERSION_P3: { + SAIL_TRY(pnm_private_read_pixels(pnm_state->io, image, 3, pnm_state->bpc, pnm_state->multiplier_to_full_range)); + break; + } + case SAIL_PNM_VERSION_P4: + case SAIL_PNM_VERSION_P5: + case SAIL_PNM_VERSION_P6: { + for (unsigned row = 0; row < image->height; row++) { + SAIL_TRY(pnm_state->io->strict_read(pnm_state->io->stream, sail_scan_line(image, row), image->bytes_per_line)); + } + break; + } + } + + return SAIL_OK; +} + +SAIL_EXPORT sail_status_t sail_codec_load_finish_v8_pnm(void **state) { + + struct pnm_state *pnm_state = *state; + + *state = NULL; + + destroy_pnm_state(pnm_state); + + return SAIL_OK; +} + +/* + * Encoding functions. + */ + +SAIL_EXPORT sail_status_t sail_codec_save_init_v8_pnm(struct sail_io *io, const struct sail_save_options *save_options, void **state) { + + (void)io; + (void)save_options; + (void)state; + + SAIL_LOG_AND_RETURN(SAIL_ERROR_NOT_IMPLEMENTED); +} + +SAIL_EXPORT sail_status_t sail_codec_save_seek_next_frame_v8_pnm(void *state, const struct sail_image *image) { + + (void)state; + (void)image; + + SAIL_LOG_AND_RETURN(SAIL_ERROR_NOT_IMPLEMENTED); +} + +SAIL_EXPORT sail_status_t sail_codec_save_frame_v8_pnm(void *state, const struct sail_image *image) { + + (void)state; + (void)image; + + SAIL_LOG_AND_RETURN(SAIL_ERROR_NOT_IMPLEMENTED); +} + +SAIL_EXPORT sail_status_t sail_codec_save_finish_v8_pnm(void **state) { + + (void)state; + + SAIL_LOG_AND_RETURN(SAIL_ERROR_NOT_IMPLEMENTED); +} diff --git a/src/sail-codecs/pnm/pnm.codec.info.in b/src/sail-codecs/pnm/pnm.codec.info.in new file mode 100644 index 00000000..6e4e991a --- /dev/null +++ b/src/sail-codecs/pnm/pnm.codec.info.in @@ -0,0 +1,26 @@ +# PNM codec information +# +[codec] +layout=8 +version=0.6.5 +priority=LOW +name=PNM +description=Portable aNy Map +magic-numbers=50 31;50 32;50 33;50 34;50 35;50 36 +extensions=pbm;pgm;ppm;pnm +mime-types=image/x-portable-bitmap;image/x-portable-graymap;image/x-portable-pixmap;image/x-portable-anymap + +[load-features] +features=STATIC;SOURCE-IMAGE +tuning= + +[save-features] +features= +pixel-formats= +compressions= +default-compression= +compression-level-min=0 +compression-level-max=0 +compression-level-default=0 +compression-level-step=0 +tuning= diff --git a/src/sail-codecs/pnm/pnm.png b/src/sail-codecs/pnm/pnm.png new file mode 100644 index 00000000..0f448d2a Binary files /dev/null and b/src/sail-codecs/pnm/pnm.png differ diff --git a/src/sail/io_file.h b/src/sail/io_file.h index 9d6b757a..cfb221c2 100644 --- a/src/sail/io_file.h +++ b/src/sail/io_file.h @@ -37,7 +37,7 @@ struct sail_io; /* * Opens the specified image file for reading and allocates a new I/O object for it. - * sail_io.stream is a pointer to a FILE. + * sail_io.stream is a pointer to a FILE. fread/fwrite/fseek/feof are used underneath. * * Returns SAIL_OK on success. */ diff --git a/tests/images/pnm/bpp1-grayscale.ascii.pbm b/tests/images/pnm/bpp1-grayscale.ascii.pbm new file mode 100644 index 00000000..caa729d6 --- /dev/null +++ b/tests/images/pnm/bpp1-grayscale.ascii.pbm @@ -0,0 +1,34 @@ +P1 +32 32 +11111111 11111111 11111111 11111111 +11111111 11111111 11111111 11111111 +11111111 11111111 11111111 11111111 +11111111 11111111 11111111 11111111 +11111111 11111111 11111111 11111111 +11111111 11111111 11111111 11111111 +11111111 11111111 11111111 11111111 +11111111 11111111 11111111 11111111 +11111111 11111111 11111111 00000000 +11111111 11111111 11111111 00000000 +11111111 11111111 11111111 00000000 +11111111 11111111 11111111 00000000 +11111111 11111111 11111111 00000000 +11111111 11111111 11111111 00000000 +11111111 11111111 11111111 00000000 +11111111 11111111 11111111 00000000 +00000000 00000000 00000000 00000000 +00000000 00000000 00000000 00000000 +00000000 00000000 00000000 00000000 +00000000 00000000 00000000 00000000 +00000000 00000000 00000000 00000000 +00000000 00000000 00000000 00000000 +00000000 00000000 00000000 00000000 +00000000 00000000 00000000 00000000 +11111111 00000000 00000000 00000000 +11111111 00000000 00000000 00000000 +11111111 00000000 00000000 00000000 +11111111 00000000 00000000 00000000 +11111111 00000000 00000000 00000000 +11111111 00000000 00000000 00000000 +11111111 00000000 00000000 00000000 +11111111 00000000 00000000 00000000 \ No newline at end of file diff --git a/tests/images/pnm/bpp1-grayscale.raw.pbm b/tests/images/pnm/bpp1-grayscale.raw.pbm new file mode 100644 index 00000000..8ebfe948 Binary files /dev/null and b/tests/images/pnm/bpp1-grayscale.raw.pbm differ diff --git a/tests/images/pnm/bpp24-rgb.ascii.pnm b/tests/images/pnm/bpp24-rgb.ascii.pnm new file mode 100644 index 00000000..6e82e9bd --- /dev/null +++ b/tests/images/pnm/bpp24-rgb.ascii.pnm @@ -0,0 +1,3076 @@ +P3 +# Created by GIMP version 2.10.36 PNM plug-in +32 32 +255 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +128 +0 +0 +128 +0 +0 +128 +0 +0 +128 +0 +0 +128 +0 +0 +128 +0 +0 +128 +0 +0 +128 +0 +0 +0 +128 +0 +0 +128 +0 +0 +128 +0 +0 +128 +0 +0 +128 +0 +0 +128 +0 +0 +128 +0 +0 +128 +0 +128 +128 +0 +128 +128 +0 +128 +128 +0 +128 +128 +0 +128 +128 +0 +128 +128 +0 +128 +128 +0 +128 +128 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +128 +0 +0 +128 +0 +0 +128 +0 +0 +128 +0 +0 +128 +0 +0 +128 +0 +0 +128 +0 +0 +128 +0 +0 +0 +128 +0 +0 +128 +0 +0 +128 +0 +0 +128 +0 +0 +128 +0 +0 +128 +0 +0 +128 +0 +0 +128 +0 +128 +128 +0 +128 +128 +0 +128 +128 +0 +128 +128 +0 +128 +128 +0 +128 +128 +0 +128 +128 +0 +128 +128 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +128 +0 +0 +128 +0 +0 +128 +0 +0 +128 +0 +0 +128 +0 +0 +128 +0 +0 +128 +0 +0 +128 +0 +0 +0 +128 +0 +0 +128 +0 +0 +128 +0 +0 +128 +0 +0 +128 +0 +0 +128 +0 +0 +128 +0 +0 +128 +0 +128 +128 +0 +128 +128 +0 +128 +128 +0 +128 +128 +0 +128 +128 +0 +128 +128 +0 +128 +128 +0 +128 +128 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +128 +0 +0 +128 +0 +0 +128 +0 +0 +128 +0 +0 +128 +0 +0 +128 +0 +0 +128 +0 +0 +128 +0 +0 +0 +128 +0 +0 +128 +0 +0 +128 +0 +0 +128 +0 +0 +128 +0 +0 +128 +0 +0 +128 +0 +0 +128 +0 +128 +128 +0 +128 +128 +0 +128 +128 +0 +128 +128 +0 +128 +128 +0 +128 +128 +0 +128 +128 +0 +128 +128 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +128 +0 +0 +128 +0 +0 +128 +0 +0 +128 +0 +0 +128 +0 +0 +128 +0 +0 +128 +0 +0 +128 +0 +0 +0 +128 +0 +0 +128 +0 +0 +128 +0 +0 +128 +0 +0 +128 +0 +0 +128 +0 +0 +128 +0 +0 +128 +0 +128 +128 +0 +128 +128 +0 +128 +128 +0 +128 +128 +0 +128 +128 +0 +128 +128 +0 +128 +128 +0 +128 +128 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +128 +0 +0 +128 +0 +0 +128 +0 +0 +128 +0 +0 +128 +0 +0 +128 +0 +0 +128 +0 +0 +128 +0 +0 +0 +128 +0 +0 +128 +0 +0 +128 +0 +0 +128 +0 +0 +128 +0 +0 +128 +0 +0 +128 +0 +0 +128 +0 +128 +128 +0 +128 +128 +0 +128 +128 +0 +128 +128 +0 +128 +128 +0 +128 +128 +0 +128 +128 +0 +128 +128 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +128 +0 +0 +128 +0 +0 +128 +0 +0 +128 +0 +0 +128 +0 +0 +128 +0 +0 +128 +0 +0 +128 +0 +0 +0 +128 +0 +0 +128 +0 +0 +128 +0 +0 +128 +0 +0 +128 +0 +0 +128 +0 +0 +128 +0 +0 +128 +0 +128 +128 +0 +128 +128 +0 +128 +128 +0 +128 +128 +0 +128 +128 +0 +128 +128 +0 +128 +128 +0 +128 +128 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +128 +0 +0 +128 +0 +0 +128 +0 +0 +128 +0 +0 +128 +0 +0 +128 +0 +0 +128 +0 +0 +128 +0 +0 +0 +128 +0 +0 +128 +0 +0 +128 +0 +0 +128 +0 +0 +128 +0 +0 +128 +0 +0 +128 +0 +0 +128 +0 +128 +128 +0 +128 +128 +0 +128 +128 +0 +128 +128 +0 +128 +128 +0 +128 +128 +0 +128 +128 +0 +128 +128 +0 +0 +0 +128 +0 +0 +128 +0 +0 +128 +0 +0 +128 +0 +0 +128 +0 +0 +128 +0 +0 +128 +0 +0 +128 +128 +0 +128 +128 +0 +128 +128 +0 +128 +128 +0 +128 +128 +0 +128 +128 +0 +128 +128 +0 +128 +128 +0 +128 +0 +128 +128 +0 +128 +128 +0 +128 +128 +0 +128 +128 +0 +128 +128 +0 +128 +128 +0 +128 +128 +0 +128 +128 +192 +192 +192 +192 +192 +192 +192 +192 +192 +192 +192 +192 +192 +192 +192 +192 +192 +192 +192 +192 +192 +192 +192 +192 +0 +0 +128 +0 +0 +128 +0 +0 +128 +0 +0 +128 +0 +0 +128 +0 +0 +128 +0 +0 +128 +0 +0 +128 +128 +0 +128 +128 +0 +128 +128 +0 +128 +128 +0 +128 +128 +0 +128 +128 +0 +128 +128 +0 +128 +128 +0 +128 +0 +128 +128 +0 +128 +128 +0 +128 +128 +0 +128 +128 +0 +128 +128 +0 +128 +128 +0 +128 +128 +0 +128 +128 +192 +192 +192 +192 +192 +192 +192 +192 +192 +192 +192 +192 +192 +192 +192 +192 +192 +192 +192 +192 +192 +192 +192 +192 +0 +0 +128 +0 +0 +128 +0 +0 +128 +0 +0 +128 +0 +0 +128 +0 +0 +128 +0 +0 +128 +0 +0 +128 +128 +0 +128 +128 +0 +128 +128 +0 +128 +128 +0 +128 +128 +0 +128 +128 +0 +128 +128 +0 +128 +128 +0 +128 +0 +128 +128 +0 +128 +128 +0 +128 +128 +0 +128 +128 +0 +128 +128 +0 +128 +128 +0 +128 +128 +0 +128 +128 +192 +192 +192 +192 +192 +192 +192 +192 +192 +192 +192 +192 +192 +192 +192 +192 +192 +192 +192 +192 +192 +192 +192 +192 +0 +0 +128 +0 +0 +128 +0 +0 +128 +0 +0 +128 +0 +0 +128 +0 +0 +128 +0 +0 +128 +0 +0 +128 +128 +0 +128 +128 +0 +128 +128 +0 +128 +128 +0 +128 +128 +0 +128 +128 +0 +128 +128 +0 +128 +128 +0 +128 +0 +128 +128 +0 +128 +128 +0 +128 +128 +0 +128 +128 +0 +128 +128 +0 +128 +128 +0 +128 +128 +0 +128 +128 +192 +192 +192 +192 +192 +192 +192 +192 +192 +192 +192 +192 +192 +192 +192 +192 +192 +192 +192 +192 +192 +192 +192 +192 +0 +0 +128 +0 +0 +128 +0 +0 +128 +0 +0 +128 +0 +0 +128 +0 +0 +128 +0 +0 +128 +0 +0 +128 +128 +0 +128 +128 +0 +128 +128 +0 +128 +128 +0 +128 +128 +0 +128 +128 +0 +128 +128 +0 +128 +128 +0 +128 +0 +128 +128 +0 +128 +128 +0 +128 +128 +0 +128 +128 +0 +128 +128 +0 +128 +128 +0 +128 +128 +0 +128 +128 +192 +192 +192 +192 +192 +192 +192 +192 +192 +192 +192 +192 +192 +192 +192 +192 +192 +192 +192 +192 +192 +192 +192 +192 +0 +0 +128 +0 +0 +128 +0 +0 +128 +0 +0 +128 +0 +0 +128 +0 +0 +128 +0 +0 +128 +0 +0 +128 +128 +0 +128 +128 +0 +128 +128 +0 +128 +128 +0 +128 +128 +0 +128 +128 +0 +128 +128 +0 +128 +128 +0 +128 +0 +128 +128 +0 +128 +128 +0 +128 +128 +0 +128 +128 +0 +128 +128 +0 +128 +128 +0 +128 +128 +0 +128 +128 +192 +192 +192 +192 +192 +192 +192 +192 +192 +192 +192 +192 +192 +192 +192 +192 +192 +192 +192 +192 +192 +192 +192 +192 +0 +0 +128 +0 +0 +128 +0 +0 +128 +0 +0 +128 +0 +0 +128 +0 +0 +128 +0 +0 +128 +0 +0 +128 +128 +0 +128 +128 +0 +128 +128 +0 +128 +128 +0 +128 +128 +0 +128 +128 +0 +128 +128 +0 +128 +128 +0 +128 +0 +128 +128 +0 +128 +128 +0 +128 +128 +0 +128 +128 +0 +128 +128 +0 +128 +128 +0 +128 +128 +0 +128 +128 +192 +192 +192 +192 +192 +192 +192 +192 +192 +192 +192 +192 +192 +192 +192 +192 +192 +192 +192 +192 +192 +192 +192 +192 +0 +0 +128 +0 +0 +128 +0 +0 +128 +0 +0 +128 +0 +0 +128 +0 +0 +128 +0 +0 +128 +0 +0 +128 +128 +0 +128 +128 +0 +128 +128 +0 +128 +128 +0 +128 +128 +0 +128 +128 +0 +128 +128 +0 +128 +128 +0 +128 +0 +128 +128 +0 +128 +128 +0 +128 +128 +0 +128 +128 +0 +128 +128 +0 +128 +128 +0 +128 +128 +0 +128 +128 +192 +192 +192 +192 +192 +192 +192 +192 +192 +192 +192 +192 +192 +192 +192 +192 +192 +192 +192 +192 +192 +192 +192 +192 +128 +128 +128 +128 +128 +128 +128 +128 +128 +128 +128 +128 +128 +128 +128 +128 +128 +128 +128 +128 +128 +128 +128 +128 +255 +0 +0 +255 +0 +0 +255 +0 +0 +255 +0 +0 +255 +0 +0 +255 +0 +0 +255 +0 +0 +255 +0 +0 +1 +255 +0 +1 +255 +0 +1 +255 +0 +1 +255 +0 +1 +255 +0 +1 +255 +0 +1 +255 +0 +1 +255 +0 +255 +255 +0 +255 +255 +0 +255 +255 +0 +255 +255 +0 +255 +255 +0 +255 +255 +0 +255 +255 +0 +255 +255 +0 +128 +128 +128 +128 +128 +128 +128 +128 +128 +128 +128 +128 +128 +128 +128 +128 +128 +128 +128 +128 +128 +128 +128 +128 +255 +0 +0 +255 +0 +0 +255 +0 +0 +255 +0 +0 +255 +0 +0 +255 +0 +0 +255 +0 +0 +255 +0 +0 +1 +255 +0 +1 +255 +0 +1 +255 +0 +1 +255 +0 +1 +255 +0 +1 +255 +0 +1 +255 +0 +1 +255 +0 +255 +255 +0 +255 +255 +0 +255 +255 +0 +255 +255 +0 +255 +255 +0 +255 +255 +0 +255 +255 +0 +255 +255 +0 +128 +128 +128 +128 +128 +128 +128 +128 +128 +128 +128 +128 +128 +128 +128 +128 +128 +128 +128 +128 +128 +128 +128 +128 +255 +0 +0 +255 +0 +0 +255 +0 +0 +255 +0 +0 +255 +0 +0 +255 +0 +0 +255 +0 +0 +255 +0 +0 +1 +255 +0 +1 +255 +0 +1 +255 +0 +1 +255 +0 +1 +255 +0 +1 +255 +0 +1 +255 +0 +1 +255 +0 +255 +255 +0 +255 +255 +0 +255 +255 +0 +255 +255 +0 +255 +255 +0 +255 +255 +0 +255 +255 +0 +255 +255 +0 +128 +128 +128 +128 +128 +128 +128 +128 +128 +128 +128 +128 +128 +128 +128 +128 +128 +128 +128 +128 +128 +128 +128 +128 +255 +0 +0 +255 +0 +0 +255 +0 +0 +255 +0 +0 +255 +0 +0 +255 +0 +0 +255 +0 +0 +255 +0 +0 +1 +255 +0 +1 +255 +0 +1 +255 +0 +1 +255 +0 +1 +255 +0 +1 +255 +0 +1 +255 +0 +1 +255 +0 +255 +255 +0 +255 +255 +0 +255 +255 +0 +255 +255 +0 +255 +255 +0 +255 +255 +0 +255 +255 +0 +255 +255 +0 +128 +128 +128 +128 +128 +128 +128 +128 +128 +128 +128 +128 +128 +128 +128 +128 +128 +128 +128 +128 +128 +128 +128 +128 +255 +0 +0 +255 +0 +0 +255 +0 +0 +255 +0 +0 +255 +0 +0 +255 +0 +0 +255 +0 +0 +255 +0 +0 +1 +255 +0 +1 +255 +0 +1 +255 +0 +1 +255 +0 +1 +255 +0 +1 +255 +0 +1 +255 +0 +1 +255 +0 +255 +255 +0 +255 +255 +0 +255 +255 +0 +255 +255 +0 +255 +255 +0 +255 +255 +0 +255 +255 +0 +255 +255 +0 +128 +128 +128 +128 +128 +128 +128 +128 +128 +128 +128 +128 +128 +128 +128 +128 +128 +128 +128 +128 +128 +128 +128 +128 +255 +0 +0 +255 +0 +0 +255 +0 +0 +255 +0 +0 +255 +0 +0 +255 +0 +0 +255 +0 +0 +255 +0 +0 +1 +255 +0 +1 +255 +0 +1 +255 +0 +1 +255 +0 +1 +255 +0 +1 +255 +0 +1 +255 +0 +1 +255 +0 +255 +255 +0 +255 +255 +0 +255 +255 +0 +255 +255 +0 +255 +255 +0 +255 +255 +0 +255 +255 +0 +255 +255 +0 +128 +128 +128 +128 +128 +128 +128 +128 +128 +128 +128 +128 +128 +128 +128 +128 +128 +128 +128 +128 +128 +128 +128 +128 +255 +0 +0 +255 +0 +0 +255 +0 +0 +255 +0 +0 +255 +0 +0 +255 +0 +0 +255 +0 +0 +255 +0 +0 +1 +255 +0 +1 +255 +0 +1 +255 +0 +1 +255 +0 +1 +255 +0 +1 +255 +0 +1 +255 +0 +1 +255 +0 +255 +255 +0 +255 +255 +0 +255 +255 +0 +255 +255 +0 +255 +255 +0 +255 +255 +0 +255 +255 +0 +255 +255 +0 +128 +128 +128 +128 +128 +128 +128 +128 +128 +128 +128 +128 +128 +128 +128 +128 +128 +128 +128 +128 +128 +128 +128 +128 +255 +0 +0 +255 +0 +0 +255 +0 +0 +255 +0 +0 +255 +0 +0 +255 +0 +0 +255 +0 +0 +255 +0 +0 +1 +255 +0 +1 +255 +0 +1 +255 +0 +1 +255 +0 +1 +255 +0 +1 +255 +0 +1 +255 +0 +1 +255 +0 +255 +255 +0 +255 +255 +0 +255 +255 +0 +255 +255 +0 +255 +255 +0 +255 +255 +0 +255 +255 +0 +255 +255 +0 +0 +0 +255 +0 +0 +255 +0 +0 +255 +0 +0 +255 +0 +0 +255 +0 +0 +255 +0 +0 +255 +0 +0 +255 +255 +0 +255 +255 +0 +255 +255 +0 +255 +255 +0 +255 +255 +0 +255 +255 +0 +255 +255 +0 +255 +255 +0 +255 +1 +255 +255 +1 +255 +255 +1 +255 +255 +1 +255 +255 +1 +255 +255 +1 +255 +255 +1 +255 +255 +1 +255 +255 +255 +255 +255 +255 +255 +255 +255 +255 +255 +255 +255 +255 +255 +255 +255 +255 +255 +255 +255 +255 +255 +255 +255 +255 +0 +0 +255 +0 +0 +255 +0 +0 +255 +0 +0 +255 +0 +0 +255 +0 +0 +255 +0 +0 +255 +0 +0 +255 +255 +0 +255 +255 +0 +255 +255 +0 +255 +255 +0 +255 +255 +0 +255 +255 +0 +255 +255 +0 +255 +255 +0 +255 +1 +255 +255 +1 +255 +255 +1 +255 +255 +1 +255 +255 +1 +255 +255 +1 +255 +255 +1 +255 +255 +1 +255 +255 +255 +255 +255 +255 +255 +255 +255 +255 +255 +255 +255 +255 +255 +255 +255 +255 +255 +255 +255 +255 +255 +255 +255 +255 +0 +0 +255 +0 +0 +255 +0 +0 +255 +0 +0 +255 +0 +0 +255 +0 +0 +255 +0 +0 +255 +0 +0 +255 +255 +0 +255 +255 +0 +255 +255 +0 +255 +255 +0 +255 +255 +0 +255 +255 +0 +255 +255 +0 +255 +255 +0 +255 +1 +255 +255 +1 +255 +255 +1 +255 +255 +1 +255 +255 +1 +255 +255 +1 +255 +255 +1 +255 +255 +1 +255 +255 +255 +255 +255 +255 +255 +255 +255 +255 +255 +255 +255 +255 +255 +255 +255 +255 +255 +255 +255 +255 +255 +255 +255 +255 +0 +0 +255 +0 +0 +255 +0 +0 +255 +0 +0 +255 +0 +0 +255 +0 +0 +255 +0 +0 +255 +0 +0 +255 +255 +0 +255 +255 +0 +255 +255 +0 +255 +255 +0 +255 +255 +0 +255 +255 +0 +255 +255 +0 +255 +255 +0 +255 +1 +255 +255 +1 +255 +255 +1 +255 +255 +1 +255 +255 +1 +255 +255 +1 +255 +255 +1 +255 +255 +1 +255 +255 +255 +255 +255 +255 +255 +255 +255 +255 +255 +255 +255 +255 +255 +255 +255 +255 +255 +255 +255 +255 +255 +255 +255 +255 +0 +0 +255 +0 +0 +255 +0 +0 +255 +0 +0 +255 +0 +0 +255 +0 +0 +255 +0 +0 +255 +0 +0 +255 +255 +0 +255 +255 +0 +255 +255 +0 +255 +255 +0 +255 +255 +0 +255 +255 +0 +255 +255 +0 +255 +255 +0 +255 +1 +255 +255 +1 +255 +255 +1 +255 +255 +1 +255 +255 +1 +255 +255 +1 +255 +255 +1 +255 +255 +1 +255 +255 +255 +255 +255 +255 +255 +255 +255 +255 +255 +255 +255 +255 +255 +255 +255 +255 +255 +255 +255 +255 +255 +255 +255 +255 +0 +0 +255 +0 +0 +255 +0 +0 +255 +0 +0 +255 +0 +0 +255 +0 +0 +255 +0 +0 +255 +0 +0 +255 +255 +0 +255 +255 +0 +255 +255 +0 +255 +255 +0 +255 +255 +0 +255 +255 +0 +255 +255 +0 +255 +255 +0 +255 +1 +255 +255 +1 +255 +255 +1 +255 +255 +1 +255 +255 +1 +255 +255 +1 +255 +255 +1 +255 +255 +1 +255 +255 +255 +255 +255 +255 +255 +255 +255 +255 +255 +255 +255 +255 +255 +255 +255 +255 +255 +255 +255 +255 +255 +255 +255 +255 +0 +0 +255 +0 +0 +255 +0 +0 +255 +0 +0 +255 +0 +0 +255 +0 +0 +255 +0 +0 +255 +0 +0 +255 +255 +0 +255 +255 +0 +255 +255 +0 +255 +255 +0 +255 +255 +0 +255 +255 +0 +255 +255 +0 +255 +255 +0 +255 +1 +255 +255 +1 +255 +255 +1 +255 +255 +1 +255 +255 +1 +255 +255 +1 +255 +255 +1 +255 +255 +1 +255 +255 +255 +255 +255 +255 +255 +255 +255 +255 +255 +255 +255 +255 +255 +255 +255 +255 +255 +255 +255 +255 +255 +255 +255 +255 +0 +0 +255 +0 +0 +255 +0 +0 +255 +0 +0 +255 +0 +0 +255 +0 +0 +255 +0 +0 +255 +0 +0 +255 +255 +0 +255 +255 +0 +255 +255 +0 +255 +255 +0 +255 +255 +0 +255 +255 +0 +255 +255 +0 +255 +255 +0 +255 +1 +255 +255 +1 +255 +255 +1 +255 +255 +1 +255 +255 +1 +255 +255 +1 +255 +255 +1 +255 +255 +1 +255 +255 +255 +255 +255 +255 +255 +255 +255 +255 +255 +255 +255 +255 +255 +255 +255 +255 +255 +255 +255 +255 +255 +255 +255 +255 diff --git a/tests/images/pnm/bpp24-rgb.raw.pnm b/tests/images/pnm/bpp24-rgb.raw.pnm new file mode 100644 index 00000000..77c67294 Binary files /dev/null and b/tests/images/pnm/bpp24-rgb.raw.pnm differ diff --git a/tests/images/pnm/bpp8-grayscale.ascii.pgm b/tests/images/pnm/bpp8-grayscale.ascii.pgm new file mode 100644 index 00000000..207de6e1 --- /dev/null +++ b/tests/images/pnm/bpp8-grayscale.ascii.pgm @@ -0,0 +1,1028 @@ +P2 +# Created by GIMP version 2.10.36 PNM plug-in +32 32 +255 +0 +0 +0 +0 +0 +0 +0 +0 +62 +62 +62 +62 +62 +62 +62 +62 +110 +110 +110 +110 +110 +110 +110 +110 +124 +124 +124 +124 +124 +124 +124 +124 +0 +0 +0 +0 +0 +0 +0 +0 +62 +62 +62 +62 +62 +62 +62 +62 +110 +110 +110 +110 +110 +110 +110 +110 +124 +124 +124 +124 +124 +124 +124 +124 +0 +0 +0 +0 +0 +0 +0 +0 +62 +62 +62 +62 +62 +62 +62 +62 +110 +110 +110 +110 +110 +110 +110 +110 +124 +124 +124 +124 +124 +124 +124 +124 +0 +0 +0 +0 +0 +0 +0 +0 +62 +62 +62 +62 +62 +62 +62 +62 +110 +110 +110 +110 +110 +110 +110 +110 +124 +124 +124 +124 +124 +124 +124 +124 +0 +0 +0 +0 +0 +0 +0 +0 +62 +62 +62 +62 +62 +62 +62 +62 +110 +110 +110 +110 +110 +110 +110 +110 +124 +124 +124 +124 +124 +124 +124 +124 +0 +0 +0 +0 +0 +0 +0 +0 +62 +62 +62 +62 +62 +62 +62 +62 +110 +110 +110 +110 +110 +110 +110 +110 +124 +124 +124 +124 +124 +124 +124 +124 +0 +0 +0 +0 +0 +0 +0 +0 +62 +62 +62 +62 +62 +62 +62 +62 +110 +110 +110 +110 +110 +110 +110 +110 +124 +124 +124 +124 +124 +124 +124 +124 +0 +0 +0 +0 +0 +0 +0 +0 +62 +62 +62 +62 +62 +62 +62 +62 +110 +110 +110 +110 +110 +110 +110 +110 +124 +124 +124 +124 +124 +124 +124 +124 +30 +30 +30 +30 +30 +30 +30 +30 +70 +70 +70 +70 +70 +70 +70 +70 +114 +114 +114 +114 +114 +114 +114 +114 +192 +192 +192 +192 +192 +192 +192 +192 +30 +30 +30 +30 +30 +30 +30 +30 +70 +70 +70 +70 +70 +70 +70 +70 +114 +114 +114 +114 +114 +114 +114 +114 +192 +192 +192 +192 +192 +192 +192 +192 +30 +30 +30 +30 +30 +30 +30 +30 +70 +70 +70 +70 +70 +70 +70 +70 +114 +114 +114 +114 +114 +114 +114 +114 +192 +192 +192 +192 +192 +192 +192 +192 +30 +30 +30 +30 +30 +30 +30 +30 +70 +70 +70 +70 +70 +70 +70 +70 +114 +114 +114 +114 +114 +114 +114 +114 +192 +192 +192 +192 +192 +192 +192 +192 +30 +30 +30 +30 +30 +30 +30 +30 +70 +70 +70 +70 +70 +70 +70 +70 +114 +114 +114 +114 +114 +114 +114 +114 +192 +192 +192 +192 +192 +192 +192 +192 +30 +30 +30 +30 +30 +30 +30 +30 +70 +70 +70 +70 +70 +70 +70 +70 +114 +114 +114 +114 +114 +114 +114 +114 +192 +192 +192 +192 +192 +192 +192 +192 +30 +30 +30 +30 +30 +30 +30 +30 +70 +70 +70 +70 +70 +70 +70 +70 +114 +114 +114 +114 +114 +114 +114 +114 +192 +192 +192 +192 +192 +192 +192 +192 +30 +30 +30 +30 +30 +30 +30 +30 +70 +70 +70 +70 +70 +70 +70 +70 +114 +114 +114 +114 +114 +114 +114 +114 +192 +192 +192 +192 +192 +192 +192 +192 +128 +128 +128 +128 +128 +128 +128 +128 +130 +130 +130 +130 +130 +130 +130 +130 +220 +220 +220 +220 +220 +220 +220 +220 +248 +248 +248 +248 +248 +248 +248 +248 +128 +128 +128 +128 +128 +128 +128 +128 +130 +130 +130 +130 +130 +130 +130 +130 +220 +220 +220 +220 +220 +220 +220 +220 +248 +248 +248 +248 +248 +248 +248 +248 +128 +128 +128 +128 +128 +128 +128 +128 +130 +130 +130 +130 +130 +130 +130 +130 +220 +220 +220 +220 +220 +220 +220 +220 +248 +248 +248 +248 +248 +248 +248 +248 +128 +128 +128 +128 +128 +128 +128 +128 +130 +130 +130 +130 +130 +130 +130 +130 +220 +220 +220 +220 +220 +220 +220 +220 +248 +248 +248 +248 +248 +248 +248 +248 +128 +128 +128 +128 +128 +128 +128 +128 +130 +130 +130 +130 +130 +130 +130 +130 +220 +220 +220 +220 +220 +220 +220 +220 +248 +248 +248 +248 +248 +248 +248 +248 +128 +128 +128 +128 +128 +128 +128 +128 +130 +130 +130 +130 +130 +130 +130 +130 +220 +220 +220 +220 +220 +220 +220 +220 +248 +248 +248 +248 +248 +248 +248 +248 +128 +128 +128 +128 +128 +128 +128 +128 +130 +130 +130 +130 +130 +130 +130 +130 +220 +220 +220 +220 +220 +220 +220 +220 +248 +248 +248 +248 +248 +248 +248 +248 +128 +128 +128 +128 +128 +128 +128 +128 +130 +130 +130 +130 +130 +130 +130 +130 +220 +220 +220 +220 +220 +220 +220 +220 +248 +248 +248 +248 +248 +248 +248 +248 +70 +70 +70 +70 +70 +70 +70 +70 +145 +145 +145 +145 +145 +145 +145 +145 +228 +228 +228 +228 +228 +228 +228 +228 +255 +255 +255 +255 +255 +255 +255 +255 +70 +70 +70 +70 +70 +70 +70 +70 +145 +145 +145 +145 +145 +145 +145 +145 +228 +228 +228 +228 +228 +228 +228 +228 +255 +255 +255 +255 +255 +255 +255 +255 +70 +70 +70 +70 +70 +70 +70 +70 +145 +145 +145 +145 +145 +145 +145 +145 +228 +228 +228 +228 +228 +228 +228 +228 +255 +255 +255 +255 +255 +255 +255 +255 +70 +70 +70 +70 +70 +70 +70 +70 +145 +145 +145 +145 +145 +145 +145 +145 +228 +228 +228 +228 +228 +228 +228 +228 +255 +255 +255 +255 +255 +255 +255 +255 +70 +70 +70 +70 +70 +70 +70 +70 +145 +145 +145 +145 +145 +145 +145 +145 +228 +228 +228 +228 +228 +228 +228 +228 +255 +255 +255 +255 +255 +255 +255 +255 +70 +70 +70 +70 +70 +70 +70 +70 +145 +145 +145 +145 +145 +145 +145 +145 +228 +228 +228 +228 +228 +228 +228 +228 +255 +255 +255 +255 +255 +255 +255 +255 +70 +70 +70 +70 +70 +70 +70 +70 +145 +145 +145 +145 +145 +145 +145 +145 +228 +228 +228 +228 +228 +228 +228 +228 +255 +255 +255 +255 +255 +255 +255 +255 +70 +70 +70 +70 +70 +70 +70 +70 +145 +145 +145 +145 +145 +145 +145 +145 +228 +228 +228 +228 +228 +228 +228 +228 +255 +255 +255 +255 +255 +255 +255 +255 diff --git a/tests/images/pnm/bpp8-grayscale.raw.pgm b/tests/images/pnm/bpp8-grayscale.raw.pgm new file mode 100644 index 00000000..3dc48079 Binary files /dev/null and b/tests/images/pnm/bpp8-grayscale.raw.pgm differ diff --git a/tests/images/test-images.h.in b/tests/images/test-images.h.in index 20092bc0..93b18856 100644 --- a/tests/images/test-images.h.in +++ b/tests/images/test-images.h.in @@ -58,6 +58,15 @@ static const char * const SAIL_TEST_IMAGES[] = { "@SAIL_TEST_IMAGES_PATH@/png/bpp4-indexed.comment.iccp.png", #endif +#ifdef SAIL_HAVE_BUILTIN_PNM + "@SAIL_TEST_IMAGES_PATH@/pnm/bpp1-grayscale.ascii.pbm", + "@SAIL_TEST_IMAGES_PATH@/pnm/bpp1-grayscale.raw.pbm", + "@SAIL_TEST_IMAGES_PATH@/pnm/bpp24-rgb.ascii.pnm", + "@SAIL_TEST_IMAGES_PATH@/pnm/bpp24-rgb.raw.pnm", + "@SAIL_TEST_IMAGES_PATH@/pnm/bpp8-grayscale.ascii.pgm", + "@SAIL_TEST_IMAGES_PATH@/pnm/bpp8-grayscale.raw.pgm", +#endif + #ifdef SAIL_HAVE_BUILTIN_PSD "@SAIL_TEST_IMAGES_PATH@/psd/bpp8-indexed.psd", "@SAIL_TEST_IMAGES_PATH@/psd/bpp24-rgb.psd",