generated from bob/template
Initial commit
This commit is contained in:
@@ -0,0 +1,99 @@
|
||||
#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;
|
||||
}
|
||||
Reference in New Issue
Block a user