From e865c3d15279235a36ee32849d0b764772543499 Mon Sep 17 00:00:00 2001 From: Armijn Hemel Date: Fri, 17 Mar 2023 21:24:59 +0100 Subject: [PATCH 01/16] add Portable Image Format (pif) --- image/pif.ksy | 58 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 image/pif.ksy diff --git a/image/pif.ksy b/image/pif.ksy new file mode 100644 index 000000000..5d4697f70 --- /dev/null +++ b/image/pif.ksy @@ -0,0 +1,58 @@ +meta: + id: pif + title: Portable Image Format + file-extension: pif + license: LGPL-2.1 + ks-version: 0.10 + endian: le +doc-ref: https://raw.githubusercontent.com/gfcwfzkm/PIF-Image-Format/main/Specification/PIF%20Format%20Specification.pdf +seq: + - id: header + type: header + - id: information_header + type: information_header + - id: color_table + size: information_header.len_color_table + - id: data + size: header.len_file - header._sizeof - information_header._sizeof - information_header.len_color_table +types: + header: + seq: + - id: signature + contents: ["PIF", 0x00] + - id: len_file + type: u4 + - id: ofs_pixel_array + type: u4 + information_header: + seq: + - id: image_type + type: u2 + enum: image_type + - id: bits_per_pixel + type: u2 + - id: width + type: u2 + - id: height + type: u2 + - id: len_image + type: u4 + - id: len_color_table + type: u2 + - id: compressed + type: u2 + valid: + any-of: [0, 0x7dde] + instances: + is_compressed: + value: compressed == 0x7dde +enums: + image_type: + 0x433c: rgb888 + 0xe5c5: rgb565 + 0x1e53: rgb332 + 0xb895: rgb16c + 0x7daa: black_white + 0x4952: indexed_24 + 0x4947: indexed_16 + 0x4942: indexed_8 From 2009cf86250cdf58330dd93e89a8c79a29554733 Mon Sep 17 00:00:00 2001 From: Petr Pucil Date: Sun, 19 Mar 2023 01:04:17 +0100 Subject: [PATCH 02/16] pif: use shortened commit hash in GitHub link to the PDF spec --- image/pif.ksy | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/image/pif.ksy b/image/pif.ksy index 5d4697f70..7e29e5e3f 100644 --- a/image/pif.ksy +++ b/image/pif.ksy @@ -5,7 +5,7 @@ meta: license: LGPL-2.1 ks-version: 0.10 endian: le -doc-ref: https://raw.githubusercontent.com/gfcwfzkm/PIF-Image-Format/main/Specification/PIF%20Format%20Specification.pdf +doc-ref: https://github.com/gfcwfzkm/PIF-Image-Format/blob/cc256d5/Specification/PIF%20Format%20Specification.pdf seq: - id: header type: header From d8bcbc075e1ca6fe1c284d3d17858af10f050074 Mon Sep 17 00:00:00 2001 From: Petr Pucil Date: Sun, 19 Mar 2023 01:08:24 +0100 Subject: [PATCH 03/16] pif: rename `signature` to `magic` per style guide See https://doc.kaitai.io/ksy_style_guide.html#attr-id --- image/pif.ksy | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/image/pif.ksy b/image/pif.ksy index 7e29e5e3f..a9c2b068f 100644 --- a/image/pif.ksy +++ b/image/pif.ksy @@ -18,7 +18,7 @@ seq: types: header: seq: - - id: signature + - id: magic contents: ["PIF", 0x00] - id: len_file type: u4 From 222f7208844fa4c5bf75e68af607229a5d76d288 Mon Sep 17 00:00:00 2001 From: Armijn Hemel Date: Sun, 19 Mar 2023 18:09:41 +0100 Subject: [PATCH 04/16] Update image/pif.ksy MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Petr Pučil --- image/pif.ksy | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/image/pif.ksy b/image/pif.ksy index a9c2b068f..ebc949779 100644 --- a/image/pif.ksy +++ b/image/pif.ksy @@ -14,7 +14,7 @@ seq: - id: color_table size: information_header.len_color_table - id: data - size: header.len_file - header._sizeof - information_header._sizeof - information_header.len_color_table + size: header.len_image types: header: seq: From 5ed568c240489b36551bbd749aeaa43103f631d4 Mon Sep 17 00:00:00 2001 From: Armijn Hemel Date: Sun, 19 Mar 2023 18:11:38 +0100 Subject: [PATCH 05/16] pif: don't require version 0.10, as it should work just fine in 0.9 --- image/pif.ksy | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/image/pif.ksy b/image/pif.ksy index ebc949779..0e02028a9 100644 --- a/image/pif.ksy +++ b/image/pif.ksy @@ -3,7 +3,7 @@ meta: title: Portable Image Format file-extension: pif license: LGPL-2.1 - ks-version: 0.10 + ks-version: 0.9 endian: le doc-ref: https://github.com/gfcwfzkm/PIF-Image-Format/blob/cc256d5/Specification/PIF%20Format%20Specification.pdf seq: From bf4a004b2cb147502439465ace0edd654b874dd3 Mon Sep 17 00:00:00 2001 From: Armijn Hemel Date: Wed, 22 Mar 2023 16:00:38 +0100 Subject: [PATCH 06/16] pif: use correct header for len_image --- image/pif.ksy | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/image/pif.ksy b/image/pif.ksy index 0e02028a9..b0a2cd74e 100644 --- a/image/pif.ksy +++ b/image/pif.ksy @@ -14,7 +14,7 @@ seq: - id: color_table size: information_header.len_color_table - id: data - size: header.len_image + size: information_header.len_image types: header: seq: From 2c24afeb5c7bc0034d46e0909dd7a45d0f9d2de8 Mon Sep 17 00:00:00 2001 From: Petr Pucil Date: Sun, 26 Mar 2023 16:34:32 +0200 Subject: [PATCH 07/16] pif: convert `compression` field to use enum --- image/pif.ksy | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/image/pif.ksy b/image/pif.ksy index b0a2cd74e..cceb6cba7 100644 --- a/image/pif.ksy +++ b/image/pif.ksy @@ -39,13 +39,17 @@ types: type: u4 - id: len_color_table type: u2 - - id: compressed + - id: compression type: u2 + enum: compression_type valid: - any-of: [0, 0x7dde] - instances: - is_compressed: - value: compressed == 0x7dde + any-of: + - compression_type::none + - compression_type::rle + enums: + compression_type: + 0: none + 0x7dde: rle enums: image_type: 0x433c: rgb888 From 21cb6f53022b11c60d6fd2bf1a7db1e65205f887 Mon Sep 17 00:00:00 2001 From: Petr Pucil Date: Sun, 26 Mar 2023 23:30:36 +0200 Subject: [PATCH 08/16] pif: rename `data` to `image_data`, use `{ofs_,len_}image_data` --- image/pif.ksy | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/image/pif.ksy b/image/pif.ksy index cceb6cba7..9447f5733 100644 --- a/image/pif.ksy +++ b/image/pif.ksy @@ -13,8 +13,8 @@ seq: type: information_header - id: color_table size: information_header.len_color_table - - id: data - size: information_header.len_image + - id: image_data + size: information_header.len_image_data types: header: seq: @@ -22,7 +22,7 @@ types: contents: ["PIF", 0x00] - id: len_file type: u4 - - id: ofs_pixel_array + - id: ofs_image_data type: u4 information_header: seq: @@ -35,7 +35,7 @@ types: type: u2 - id: height type: u2 - - id: len_image + - id: len_image_data type: u4 - id: len_color_table type: u2 From cd96c271e07d0770f74f0f6f487e710e9d508af0 Mon Sep 17 00:00:00 2001 From: Petr Pucil Date: Sun, 26 Mar 2023 23:51:26 +0200 Subject: [PATCH 09/16] pif: rename `indexed_{24,16,8}` to `indexed_rgb{888,565,332}` --- image/pif.ksy | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/image/pif.ksy b/image/pif.ksy index 9447f5733..afc80213a 100644 --- a/image/pif.ksy +++ b/image/pif.ksy @@ -57,6 +57,6 @@ enums: 0x1e53: rgb332 0xb895: rgb16c 0x7daa: black_white - 0x4952: indexed_24 - 0x4947: indexed_16 - 0x4942: indexed_8 + 0x4952: indexed_rgb888 + 0x4947: indexed_rgb565 + 0x4942: indexed_rgb332 From 29121bde12f442a9e2a005b24418ab1df30c05b6 Mon Sep 17 00:00:00 2001 From: Petr Pucil Date: Mon, 27 Mar 2023 00:04:37 +0200 Subject: [PATCH 10/16] pif: rename header types to `{file,info}_header --- image/pif.ksy | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/image/pif.ksy b/image/pif.ksy index afc80213a..19ab1d630 100644 --- a/image/pif.ksy +++ b/image/pif.ksy @@ -7,16 +7,16 @@ meta: endian: le doc-ref: https://github.com/gfcwfzkm/PIF-Image-Format/blob/cc256d5/Specification/PIF%20Format%20Specification.pdf seq: - - id: header - type: header - - id: information_header + - id: file_header + type: pif_header + - id: info_header type: information_header - id: color_table - size: information_header.len_color_table + size: info_header.len_color_table - id: image_data - size: information_header.len_image_data + size: info_header.len_image_data types: - header: + pif_header: seq: - id: magic contents: ["PIF", 0x00] From 0605b8650be1564c5c03990fe38ba16023516f1e Mon Sep 17 00:00:00 2001 From: Petr Pucil Date: Mon, 27 Mar 2023 00:23:16 +0200 Subject: [PATCH 11/16] pif: move `compression_type` enum to the top level --- image/pif.ksy | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/image/pif.ksy b/image/pif.ksy index 19ab1d630..a247adee7 100644 --- a/image/pif.ksy +++ b/image/pif.ksy @@ -46,10 +46,6 @@ types: any-of: - compression_type::none - compression_type::rle - enums: - compression_type: - 0: none - 0x7dde: rle enums: image_type: 0x433c: rgb888 @@ -60,3 +56,6 @@ enums: 0x4952: indexed_rgb888 0x4947: indexed_rgb565 0x4942: indexed_rgb332 + compression_type: + 0x0000: none + 0x7dde: rle From 54524fa2afd9ac33caa4868c4a4b3b6312c98a21 Mon Sep 17 00:00:00 2001 From: Petr Pucil Date: Mon, 27 Mar 2023 00:37:16 +0200 Subject: [PATCH 12/16] pif: add descriptions to `image_type::{rgb16c,black_white}` --- image/pif.ksy | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/image/pif.ksy b/image/pif.ksy index a247adee7..76c1e7c28 100644 --- a/image/pif.ksy +++ b/image/pif.ksy @@ -51,8 +51,23 @@ enums: 0x433c: rgb888 0xe5c5: rgb565 0x1e53: rgb332 - 0xb895: rgb16c - 0x7daa: black_white + 0xb895: + id: rgb16c + doc: | + Formula to convert the 4-bit color value in RGB16C mode to RGB values + (each in the range from 0 to 255): + + ``` + red = 170 * ((color_value & 0b0100) >> 2) + 85 * ((color_value & 0b1000) >> 3) + green = 170 * ((color_value & 0b0010) >> 1) + 85 * ((color_value & 0b1000) >> 3) + blue = 170 * ((color_value & 0b0001) >> 0) + 85 * ((color_value & 0b1000) >> 3) + ``` + + See also + 0x7daa: + id: black_white + doc: '0: black, 1: white' + doc-ref: https://github.com/gfcwfzkm/PIF-Image-Format/blob/cc256d5/C%20Library/pifdec.c#L233 0x4952: indexed_rgb888 0x4947: indexed_rgb565 0x4942: indexed_rgb332 From 0a0c70f3a87ef710ea381dd2db4f70efbc660cec Mon Sep 17 00:00:00 2001 From: Petr Pucil Date: Mon, 27 Mar 2023 00:53:29 +0200 Subject: [PATCH 13/16] pif: parse color table, validate header fields --- image/pif.ksy | 66 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/image/pif.ksy b/image/pif.ksy index 76c1e7c28..d44cd4649 100644 --- a/image/pif.ksy +++ b/image/pif.ksy @@ -5,6 +5,7 @@ meta: license: LGPL-2.1 ks-version: 0.9 endian: le + bit-endian: le doc-ref: https://github.com/gfcwfzkm/PIF-Image-Format/blob/cc256d5/Specification/PIF%20Format%20Specification.pdf seq: - id: file_header @@ -13,6 +14,8 @@ seq: type: information_header - id: color_table size: info_header.len_color_table + type: color_table_data + if: info_header.uses_indexed_mode - id: image_data size: info_header.len_image_data types: @@ -29,8 +32,33 @@ types: - id: image_type type: u2 enum: image_type + valid: + any-of: + - image_type::rgb888 + - image_type::rgb565 + - image_type::rgb332 + - image_type::rgb16c + - image_type::black_white + - image_type::indexed_rgb888 + - image_type::indexed_rgb565 + - image_type::indexed_rgb332 - id: bits_per_pixel type: u2 + valid: + expr: | + image_type == image_type::rgb888 ? _ == 24 : + image_type == image_type::rgb565 ? _ == 16 : + image_type == image_type::rgb332 ? _ == 8 : + image_type == image_type::rgb16c ? _ == 4 : + image_type == image_type::black_white ? _ == 1 : + uses_indexed_mode ? _ <= 8 : + true + # ^ shouldn't get there (all cases have been covered before) + doc: | + See : + + > Bits per Pixel: Bit size that each Pixel occupies. Bit size for an + > Indexed Image cannot go beyond 8 bits. - id: width type: u2 - id: height @@ -39,6 +67,21 @@ types: type: u4 - id: len_color_table type: u2 + valid: + min: 'uses_indexed_mode ? len_color_table_entry * 1 : 0' + max: 'uses_indexed_mode ? len_color_table_entry * (1 << bits_per_pixel) : 0' + doc: | + See : + + > Color Table Size: (...), only used in Indexed mode, otherwise zero. + --- + > **Note**: The presence of the Color Table is mandatory when Bits per + > Pixel <= 8, unless Image Type states RGB332, RGB16C or B/W + --- + > **Color Table** (semi-optional) + > + > (...) The amount of Colors has to be same or less than [Bits per + > Pixel] allow, otherwise the image is invalid. - id: compression type: u2 enum: compression_type @@ -46,6 +89,29 @@ types: any-of: - compression_type::none - compression_type::rle + instances: + len_color_table_entry: + value: | + image_type == image_type::indexed_rgb888 ? 3 : + image_type == image_type::indexed_rgb565 ? 2 : + image_type == image_type::indexed_rgb332 ? 1 : + 0 + uses_indexed_mode: + value: len_color_table_entry != 0 + num_color_table_entries: + value: len_color_table / len_color_table_entry + if: uses_indexed_mode + color_table_data: + seq: + - id: entries + type: + switch-on: _root.info_header.image_type + cases: + image_type::indexed_rgb888: b24 + image_type::indexed_rgb565: b16 + image_type::indexed_rgb332: b8 + repeat: expr + repeat-expr: _root.info_header.num_color_table_entries enums: image_type: 0x433c: rgb888 From c7f93be159edbdecb6516f834377e04a7e78f0ee Mon Sep 17 00:00:00 2001 From: Petr Pucil Date: Mon, 27 Mar 2023 01:47:56 +0200 Subject: [PATCH 14/16] pif: convert `image_data` to an instance, check sizes and offsets --- image/pif.ksy | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/image/pif.ksy b/image/pif.ksy index d44cd4649..4de413f1e 100644 --- a/image/pif.ksy +++ b/image/pif.ksy @@ -16,7 +16,9 @@ seq: size: info_header.len_color_table type: color_table_data if: info_header.uses_indexed_mode - - id: image_data +instances: + image_data: + pos: file_header.ofs_image_data size: info_header.len_image_data types: pif_header: @@ -27,6 +29,12 @@ types: type: u4 - id: ofs_image_data type: u4 + valid: + min: ofs_image_data_min + max: len_file + instances: + ofs_image_data_min: + value: _root.file_header._sizeof + _root.info_header._sizeof information_header: seq: - id: image_type @@ -65,11 +73,18 @@ types: type: u2 - id: len_image_data type: u4 + valid: + max: _root.file_header.len_file - _root.file_header.ofs_image_data - id: len_color_table type: u2 valid: min: 'uses_indexed_mode ? len_color_table_entry * 1 : 0' - max: 'uses_indexed_mode ? len_color_table_entry * (1 << bits_per_pixel) : 0' + max: | + uses_indexed_mode ? ( + len_color_table_max < len_color_table_full + ? len_color_table_max + : len_color_table_full + ) : 0 doc: | See : @@ -96,6 +111,10 @@ types: image_type == image_type::indexed_rgb565 ? 2 : image_type == image_type::indexed_rgb332 ? 1 : 0 + len_color_table_full: + value: len_color_table_entry * (1 << bits_per_pixel) + len_color_table_max: + value: _root.file_header.ofs_image_data - _root.file_header.ofs_image_data_min uses_indexed_mode: value: len_color_table_entry != 0 num_color_table_entries: From 07d7e6a9daff06b1f03508cd398eb544671f13d2 Mon Sep 17 00:00:00 2001 From: Petr Pucil Date: Mon, 27 Mar 2023 03:25:20 +0200 Subject: [PATCH 15/16] pif: add `/doc` and `/meta/xref`, add "pifdec.c" to `/doc-ref` --- image/pif.ksy | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/image/pif.ksy b/image/pif.ksy index 4de413f1e..be07348b2 100644 --- a/image/pif.ksy +++ b/image/pif.ksy @@ -2,11 +2,21 @@ meta: id: pif title: Portable Image Format file-extension: pif + xref: + justsolve: PIF_(Portable_Image_Format) license: LGPL-2.1 ks-version: 0.9 endian: le bit-endian: le -doc-ref: https://github.com/gfcwfzkm/PIF-Image-Format/blob/cc256d5/Specification/PIF%20Format%20Specification.pdf +doc: | + The Portable Image Format (PIF) is a basic, bitmap-like image format with the + focus on ease of use (implementation) and small size for embedded + applications. + + See for more info. +doc-ref: + - https://github.com/gfcwfzkm/PIF-Image-Format/blob/cc256d5/Specification/PIF%20Format%20Specification.pdf + - https://github.com/gfcwfzkm/PIF-Image-Format/blob/cc256d5/C%20Library/pifdec.c#L300 seq: - id: file_header type: pif_header From d435f2ff4fe93093911b7954388e48efb50db0e3 Mon Sep 17 00:00:00 2001 From: Petr Pucil Date: Mon, 27 Mar 2023 04:02:38 +0200 Subject: [PATCH 16/16] pif: check `len_file >= ofs_image_data_min` explicitly Although this was already implicitly enforced by the combination of `valid/{min,max}` in `ofs_image_data`, it's better to do it directly in `len_file` too. The reason is that if it wasn't true, the validation error would now only be reported in `ofs_image_data`, but in fact there would be no valid value for `ofs_image_data` because `len_file` was already wrong. --- image/pif.ksy | 2 ++ 1 file changed, 2 insertions(+) diff --git a/image/pif.ksy b/image/pif.ksy index be07348b2..c51398847 100644 --- a/image/pif.ksy +++ b/image/pif.ksy @@ -37,6 +37,8 @@ types: contents: ["PIF", 0x00] - id: len_file type: u4 + valid: + min: ofs_image_data_min - id: ofs_image_data type: u4 valid: