Does this pass your Stability-Sniff-Test?#include "bmp_handler.h"

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// BMP file header structure (14 bytes)
#pragma pack(push, 1)
typedef struct {
    unsigned short type;      // Magic identifier: 0x4D42 (BM)
    unsigned int   size;      // File size in bytes
    unsigned short reserved1; // Not used
    unsigned short reserved2; // Not used
    unsigned int   offset;    // Offset to image data in bytes
} BMPHeader;

// BMP info header structure (40 bytes)
typedef struct {
    unsigned int   size;          // Header size in bytes
    int            width;         // Image width in pixels
    int            height;        // Image height in pixels
    unsigned short planes;        // Number of color planes (must be 1)
    unsigned short bits;          // Bits per pixel (24 for our case)
    unsigned int   compression;   // Compression type (0 for BI_RGB)
    unsigned int   image_size;    // Image size in bytes (can be 0 for BI_RGB)
    int            x_resolution;  // Pixels per meter
    int            y_resolution;  // Pixels per meter
    unsigned int   n_colors;      // Number of colors (0 for 24-bit)
    unsigned int   n_important_colors; // All colors are important
} BMPInfoHeader;
#pragma pack(pop)

Image* read_bmp_to_grayscale(const char* filename) {
    FILE* f = fopen(filename, "rb");
    if (!f) {
        fprintf(stderr, "Error: Could not open file %s\n", filename);
        return NULL;
    }

    BMPHeader header;
    BMPInfoHeader info_header;

    fread(&header, sizeof(BMPHeader), 1, f);
    fread(&info_header, sizeof(BMPInfoHeader), 1, f);

    if (header.type != 0x4D42) { // Check for 'BM'
        fprintf(stderr, "Error: Not a valid BMP file.\n");
        fclose(f);
        return NULL;
    }
    if (info_header.bits != 24) {
        fprintf(stderr, "Error: Only 24-bit BMP files are supported.\n");
        fclose(f);
        return NULL;
    }

    Image* img = (Image*)malloc(sizeof(Image));
    img->width = info_header.width;
    img->height = abs(info_header.height); // Height can be negative
    img->data = (unsigned char*)malloc(img->width * img->height);

    fseek(f, header.offset, SEEK_SET);

    int row_padded = (img->width * 3 + 3) & (~3);
    unsigned char* row = (unsigned char*)malloc(row_padded);

    for (int i = 0; i < img->height; i++) {
        fread(row, row_padded, 1, f);
        for (int j = 0; j < img->width; j++) {
            // Convert to grayscale using luminosity method (0.299*R + 0.587*G + 0.114*B)
            float r = row[j * 3 + 2];
            float g = row[j * 3 + 1];
            float b = row[j * 3];
            img->data[i * img->width + j] = (unsigned char)(0.299f * r + 0.587f * g + 0.114f * b);
        }
    }

    free(row);
    fclose(f);
    return img;
}

int write_grayscale_to_bmp(const char* filename, const Image* image) {
    FILE* f = fopen(filename, "wb");
    if (!f) {
        fprintf(stderr, "Error: Could not open file %s for writing.\n", filename);
        return -1;
    }

    int width = image->width;
    int height = image->height;
    int row_padded = (width * 3 + 3) & (~3);
    int image_size = row_padded * height;

    BMPHeader header = {0};
    header.type = 0x4D42;
    header.size = sizeof(BMPHeader) + sizeof(BMPInfoHeader) + image_size;
    header.offset = sizeof(BMPHeader) + sizeof(BMPInfoHeader);

    BMPInfoHeader info_header = {0};
    info_header.size = sizeof(BMPInfoHeader);
    info_header.width = width;
    info_header.height = height;
    info_header.planes = 1;
    info_header.bits = 24;
    info_header.compression = 0;
    info_header.image_size = image_size;

    fwrite(&header, sizeof(BMPHeader), 1, f);
    fwrite(&info_header, sizeof(BMPInfoHeader), 1, f);

    unsigned char* row = (unsigned char*)calloc(row_padded, 1);

    for (int i = 0; i < height; i++) {
        for (int j = 0; j < width; j++) {
            unsigned char pixel_val = image->data[i * width + j];
            row[j * 3] = pixel_val;     // Blue
            row[j * 3 + 1] = pixel_val; // Green
            row[j * 3 + 2] = pixel_val; // Red
        }
        fwrite(row, row_padded, 1, f);
    }

    free(row);
    fclose(f);
    return 0;
}

void free_image(Image* image) {
    if (image) {
        free(image->data);
        free(image);
    }
}