// Part of JoeyLib, Copyright (c) 2026 Scott Duensing, under the MIT License. // See LICENSE.md for license information. // SPDX-License-Identifier: MIT // // gateImage.h - screenshots and icons for the gate tools. // // A gate's screenshot (a PNG of any color type and bit depth) or an icon // (a BMP, or an ICO's picture) is read as RGBA, four bytes a pixel. Beside // that: the tolerant search for an icon on a screen, the nearest of a // palette's colors, and KEYS's palette and the row it stamps // (examples/keys). #ifndef GATE_IMAGE_H #define GATE_IMAGE_H #include #include #include #include "toolBuf.h" #define GATE_RGB_BYTES 3u #define GATE_RGBA_BYTES 4u #define GATE_ALPHA 3u #define GATE_KEYS_COLORS 16u // A picture: RGBA, four bytes a pixel, row after row. typedef struct GateImageT { uint32_t width; uint32_t height; uint8_t *rgba; } GateImageT; // One opaque pixel of an icon: where it is in the icon, and its color. typedef struct GateIconPixelT { uint32_t x; uint32_t y; uint8_t rgb[GATE_RGB_BYTES]; } GateIconPixelT; // An icon to look for: its size (it must lie wholly on the screen) and its // opaque pixels, in the order they were added. typedef struct GateIconT { uint32_t width; uint32_t height; uint32_t count; uint32_t cap; GateIconPixelT *pixels; } GateIconT; // The squared distance between two RGB colors. uint32_t gateDistance(const uint8_t *a, const uint8_t *b); // Print bytes as upper-case hex, two digits a byte, to stdout. void gateHexPrint(const uint8_t *data, size_t len); // Add an opaque pixel to an icon (running out of memory is fatal). void gateIconAdd(GateIconT *icon, uint32_t x, uint32_t y, const uint8_t *rgb); // Where the screen shows the icon: every opaque pixel within tolerance a // gun of its color. The search anchors on the opaque pixel whose color // the screen holds least (the first of equals) and tries the icon at each // place that color is, top to bottom, left to right; the first place the // whole icon fits and matches is the answer. An icon with no opaque pixel // is fatal. bool gateIconFind(const GateImageT *screen, const GateIconT *icon, uint32_t tolerance, uint32_t *left, uint32_t *top); // Free an icon's pixels (the struct is the caller's). void gateIconFree(GateIconT *icon); // Free a picture's pixels (the struct is the caller's). void gateImageFree(GateImageT *img); // Whether (x, y) is on the picture. bool gateImageHas(const GateImageT *img, long x, long y); // Load a PNG, BMP, or ICO (its default picture: the largest, and of those // the one of fewest colors). Anything unreadable is fatal. void gateImageLoad(const char *path, GateImageT *img); // As gateImageLoad, but an ICO gives its side x side picture of bpp bits // (any bits when bpp is 0), else its default picture. void gateImageLoadIcon(const char *path, uint32_t side, uint32_t bpp, GateImageT *img); // The pixel at (x, y), which must be on the picture. const uint8_t *gateImagePixel(const GateImageT *img, uint32_t x, uint32_t y); // KEYS's verification row for target as bytes: the sentinel A5 A5, the // count, a zero, then the characters. A target that is not ASCII, or is // longer than a count byte holds, is a bad argument (gateArgBad). void gateKeysExpect(const char *target, ToolBufT *expect); // KEYS's palette 0 (examples/keys buildPalette) as 12-bit $0RGB words. void gateKeysPalette(uint16_t words[GATE_KEYS_COLORS]); // Little-endian 16- and 32-bit numbers at p. uint32_t gateLe16(const uint8_t *p); uint32_t gateLe32(const uint8_t *p); // The palette entry nearest rgb (squared distance, the first of equals), // and that distance. uint32_t gateNearest(const uint8_t *rgb, const uint8_t (*palette)[GATE_RGB_BYTES], uint32_t count, uint32_t *distance); // A $0RGB word as 8-bit RGB, each 4-bit gun widened x17. void gateRgb12(uint32_t word, uint8_t *rgb); #endif