pebble/src/fw/applib/graphics/gbitmap_pbi.h
Josh Soref 21884a76f2 spelling: corresponds
Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com>
2025-01-28 21:32:34 -05:00

97 lines
4.5 KiB
C

/*
* Copyright 2024 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.
*/
#pragma once
//! @addtogroup Foundation
//! @{
//! @addtogroup Resources
//! @{
//! @addtogroup FileFormats File Formats
//! @{
//! @addtogroup PBIFileFormat PBI File Format
//!
//! PBIs are uncompressed bitmap images with support for color-mapping palettes.
//! PBIs store images either as raw image pixels (1-bit black and white, or 8-bit ARGB) or as
//! palette-based images with 1, 2, or 4 bits per pixel.
//! For palette-based images the pixel data represents the index into the palette, such
//! that each pixel only needs to be large enough to represent the palette size, so
//! \li \c 1-bit supports up to 2 colors,
//! \li \c 2-bit supports up to 4 colors,
//! \li \c 4-bit supports up to 16 colors.
//!
//! The metadata describes how long each row of pixels is in the buffer (the stride).
//! The following restrictions on stride are in place for different formats:
//!
//! - \ref GBitmapFormat1Bit:
//! Each row must be a multiple of 32 pixels (4 bytes). Using the `bounds` field,
//! the area that is actually relevant can be specified.
//! For example, when the image is 29 by 5 pixels
//! (width by height) and the first bit of image data is the pixel at (0, 0),
//! then the bounds.size would be `GSize(29, 5)` and bounds.origin would be `GPoint(0, 0)`.
//! ![](gbitmap.png)
//! In the illustration each pixel is a representated as a square. The white
//! squares are the bits that are used, the gray squares are the padding bits, because
//! each row of image data has to be a multiple of 4 bytes (32 bits).
//! The numbers in the column in the left are the offsets (in bytes) from the `*addr`
//! field of the GBitmap.
//! Each pixel in a bitmap is represented by 1 bit. If a bit is set (`1` or `true`),
//! it will result in a white pixel, and vice versa, if a bit is cleared (`0` or `false`),
//! it will result in a black pixel.
//! ![](pixel_bit_values.png)
//!
//! - \ref GBitmapFormat8Bit:
//! Each pixel in the bitmap is represented by 1 byte. The color value of that byte corresponds to
//! a GColor.argb value.
//! There is no restriction on row_size_bytes / stride.
//!
//! - \ref GBitmapFormat1BitPalette, \ref GBitmapFormat2BitPalette, \ref GBitmapFormat4BitPalette:
//! Each pixel in the bitmap is represented by the number of bits the format specifies. Pixels
//! must be packed.
//! For example, in GBitmapFormat2BitPalette, each pixel uses 2 bits. This means 4 pixels / byte.
//! Rows need to be byte-aligned, meaning that there can be up to 3 unused pixels at the end of
//! each line. If the image is 5 pixels wide and 4 pixels tall, row_size_bytes = 2,
//! and each row in the bitmap must take 2 bytes, so the bitmap data is 8 bytes in total.
//!
//! Palettized bitmaps also need to have a palette. The palette must be of the correct size, which
//! is specified by the format. For example, \ref GBitmapFormat4BitPalette uses 4 bits per pixel,
//! meaning that there must be 2^4 = 16 colors in the palette.
//!
//! The Basalt Platform provides for 2-bits per color channel, so images are optimized by the
//! SDK tooling when loaded as a resource-type "pbi" to the Pebble's 64-colors with 4 levels
//! of transparency. This optimization also handles mapping unsupported colors to the nearest
//! supported color, and reducing the pixel depth to the number of bits required to support
//! the optimized number of colors.
//!
//! @see \ref gbitmap_create_with_data
//! @see \ref gbitmap_create_with_resource
//!
//! @{
//! @} // end addtogroup pbi_file_format
//! @} // end addtogroup FileFormats
//! @} // end addtogroup Resources
//! @} // end addtogroup Foundation
//! This struct is used to either embed bitmap data directly into the software image or when
//! reading resources from SPI flash.
typedef struct __attribute__((__packed__)) {
uint16_t row_size_bytes;
uint16_t info_flags;
uint16_t deprecated[2];
uint16_t width;
uint16_t height;
uint8_t data[]; // Pixel data followed by an optional palette
} BitmapData;