- DUP-01: les tres branques del switch d'extensions que saltaven el mateix (bloc fix + sub-blocs) es substitueixen per una crida a skipExtensionBlock(); com que totes les extensions comparteixen layout, el switch desapareix i el codi es redueix a una línia. - DUP-06: el constructor Surface(file_path) llegia el fitxer dues voltes (una via loadSurface per pixels i una altra via loadPaletteFromGif per la paleta); ara carrega el buffer una sola vegada i n'extrau pixels + paleta en passades separades sobre la memòria. Surface::loadSurface passa a no existir públicament (no tenia callers externs). - HC-03: les màscares i talls màgics del decoder LZW i del Screen Descriptor passen a constants nominals (LZW_MIN/MAX_CODE_LENGTH, LZW_MASK_INITIAL, LZW_MASK_OVERFLOW, SCREEN_GCT_FLAG, SCREEN_GCT_SIZE_MASK, GCT_BYTES_PER_ENTRY). - HC-10: processImageDescriptor tenia gct i resolution_bits [[maybe_unused]] vestigials; se'n treu la signatura. L'struct RGB, que només servia per a aquests args, també s'elimina. - PATCH-05: el comentari "reemplaçar macro READ" (migració parcial des de C) passa a ser un comentari neutre sobre el que fa readBytes. Build + smoke 5s xvfb OK (exit 124). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
67 lines
2.3 KiB
C++
67 lines
2.3 KiB
C++
#pragma once
|
|
|
|
#include <cstdint> // Para uint8_t, uint16_t, uint32_t
|
|
#include <vector> // Para vector
|
|
|
|
namespace GIF {
|
|
|
|
// Constantes definidas con constexpr, en lugar de macros
|
|
constexpr uint8_t EXTENSION_INTRODUCER = 0x21;
|
|
constexpr uint8_t IMAGE_DESCRIPTOR = 0x2C;
|
|
constexpr uint8_t TRAILER = 0x3B;
|
|
constexpr uint8_t GRAPHIC_CONTROL = 0xF9;
|
|
constexpr uint8_t APPLICATION_EXTENSION = 0xFF;
|
|
constexpr uint8_t COMMENT_EXTENSION = 0xFE;
|
|
constexpr uint8_t PLAINTEXT_EXTENSION = 0x01;
|
|
|
|
#pragma pack(push, 1)
|
|
struct ScreenDescriptor {
|
|
uint16_t width;
|
|
uint16_t height;
|
|
uint8_t fields;
|
|
uint8_t background_color_index;
|
|
uint8_t pixel_aspect_ratio;
|
|
};
|
|
|
|
struct ImageDescriptor {
|
|
uint16_t image_left_position;
|
|
uint16_t image_top_position;
|
|
uint16_t image_width;
|
|
uint16_t image_height;
|
|
uint8_t fields;
|
|
};
|
|
#pragma pack(pop)
|
|
|
|
struct DictionaryEntry {
|
|
uint8_t byte;
|
|
int prev;
|
|
int len;
|
|
};
|
|
|
|
class Gif {
|
|
public:
|
|
// Descompone (uncompress) el bloque comprimido usando LZW.
|
|
// Este método puede lanzar std::runtime_error en caso de error.
|
|
static void decompress(int code_length, const uint8_t* input, int input_length, uint8_t* out);
|
|
|
|
// Carga la paleta (global color table) a partir de un buffer,
|
|
// retornándola en un vector de uint32_t (cada color se compone de R, G, B).
|
|
static auto loadPalette(const uint8_t* buffer) -> std::vector<uint32_t>;
|
|
|
|
// Carga el stream GIF; devuelve un vector con los datos de imagen sin comprimir y
|
|
// asigna el ancho y alto mediante referencias.
|
|
static auto loadGif(const uint8_t* buffer, uint16_t& w, uint16_t& h) -> std::vector<uint8_t>;
|
|
|
|
private:
|
|
// Lee los sub-bloques de datos y los acumula en un std::vector<uint8_t>.
|
|
static auto readSubBlocks(const uint8_t*& buffer) -> std::vector<uint8_t>;
|
|
|
|
// Procesa el Image Descriptor y retorna el vector de datos sin comprimir.
|
|
static auto processImageDescriptor(const uint8_t*& buffer) -> std::vector<uint8_t>;
|
|
|
|
// Procesa el stream completo del GIF y devuelve los datos sin comprimir.
|
|
static auto processGifStream(const uint8_t* buffer, uint16_t& w, uint16_t& h) -> std::vector<uint8_t>;
|
|
};
|
|
|
|
} // namespace GIF
|