Files
ssss/image_proc.c
T
2026-09-16 16:06:51 +08:00

99 lines
2.9 KiB
C

#include "image_proc.h"
#include <stdlib.h>
#include <string.h>
#include <windows.h>
int ExtractGray(const uint8_t *srcPixels, int w, int h, int bpp, GrayImage *outImg){
if(!srcPixels || w<=0 || h<=0) return 0;
int srcBytesPerPixel = bpp / 8;
int srcStride = ((w * srcBytesPerPixel + 3) / 4) * 4;
outImg->width = w;
outImg->height = h;
outImg->stride = w;
size_t total = (size_t)w * h;
outImg->data = (uint8_t*)malloc(total);
if(!outImg->data) return 0;
outImg->rows = (uint8_t**)malloc(sizeof(uint8_t*) * h);
if(!outImg->rows){
free(outImg->data);
outImg->data = NULL;
return 0;
}
for(int y=0; y<h; ++y){
outImg->rows[y] = outImg->data + (size_t)y * w;
}
for(int y=0; y<h; ++y){
const uint8_t *srcLine = srcPixels + (size_t)(h - 1 - y) * srcStride;
uint8_t *dstLine = outImg->rows[y];
if(bpp == 8){
memcpy(dstLine, srcLine, (size_t)w);
} else if(bpp == 24 || bpp == 32){
for(int x=0; x<w; ++x){
const uint8_t *p = srcLine + x * srcBytesPerPixel;
uint8_t B = p[0], G = p[1], R = p[2];
uint8_t Y = (uint8_t)((R*77 + G*150 + B*29) >> 8);
dstLine[x] = Y;
}
} else {
free(outImg->rows); free(outImg->data);
memset(outImg,0,sizeof(*outImg));
return 0;
}
}
return 1;
}
void FreeGray(GrayImage *img){
if(!img) return;
free(img->rows);
free(img->data);
memset(img,0,sizeof(*img));
}
int Build8BitDIB(const GrayImage *img, BITMAPINFO **outBMI, uint8_t **outPixels){
if(!img || !img->data) return 0;
int w = img->width;
int h = img->height;
int bpp = 8;
int dstStride = ((w * (bpp/8) + 3)/4)*4;
size_t pixelBytes = (size_t)dstStride * h;
size_t bmiSize = sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD);
BITMAPINFO *bmi = (BITMAPINFO*)calloc(1, bmiSize);
if(!bmi) return 0;
bmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bmi->bmiHeader.biWidth = w;
bmi->bmiHeader.biHeight = h;
bmi->bmiHeader.biPlanes = 1;
bmi->bmiHeader.biBitCount = 8;
bmi->bmiHeader.biCompression = BI_RGB;
bmi->bmiHeader.biSizeImage = (DWORD)pixelBytes;
bmi->bmiHeader.biClrUsed = 256;
for(int i=0;i<256;i++){
bmi->bmiColors[i].rgbBlue = (BYTE)i;
bmi->bmiColors[i].rgbGreen = (BYTE)i;
bmi->bmiColors[i].rgbRed = (BYTE)i;
bmi->bmiColors[i].rgbReserved = 0;
}
uint8_t *pixels = (uint8_t*)malloc(pixelBytes);
if(!pixels){
free(bmi);
return 0;
}
for(int y=0; y<h; ++y){
uint8_t *dstLine = pixels + (size_t)(h - 1 - y) * dstStride;
const uint8_t *srcLine = img->rows[y];
memcpy(dstLine, srcLine, (size_t)w);
if(dstStride > w){
memset(dstLine + w, 0, dstStride - w);
}
}
*outBMI = bmi;
*outPixels = pixels;
return 1;
}