bmp_v1/idk.c

181 lines
5.7 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include <stdlib.h>
#include <stdio.h>
#include <inttypes.h>
typedef unsigned char uch;
// ™n°¸½Y˜
#pragma pack(2)
struct BmpFileHeader {
uint16_t bfTybe;
uint32_t bfSize;
uint16_t bfReserved1;
uint16_t bfReserved2;
uint32_t bfOffBits;
};
struct BmpInfoHeader {
uint32_t biSize;
uint32_t biWidth;
uint32_t biHeight;
uint16_t biPlanes; // 1=defeaul, 0=custom
uint16_t biBitCount;
uint32_t biCompression;
uint32_t biSizeImage;
uint32_t biXPelsPerMeter; // 72dpi=2835, 96dpi=3780
uint32_t biYPelsPerMeter; // 120dpi=4724, 300dpi=11811
uint32_t biClrUsed;
uint32_t biClrImportant;
};
#pragma pack()
void bmpWrite(const char* name, const uch* raw_img,
uint32_t width, uint32_t height, uint16_t bits, float radio_w, float radio_h)
{
if(!(name && raw_img)) {
perror("Error bmpWrite.");
return;
}
// ™n°¸ÙYÓ<59>
struct BmpFileHeader file_h = {
.bfTybe=0x4d42,
.bfReserved1=0,
.bfReserved2=0,
.bfOffBits=54,
};
uint32_t new_width = width*radio_w;
uint32_t new_height = height*radio_h;
file_h.bfSize = file_h.bfOffBits + new_width*new_height * bits/8;
if(bits==8) {file_h.bfSize+= 1024, file_h.bfOffBits+= 1024;}
// ˆDƬÙYÓ<59>
struct BmpInfoHeader info_h = {
.biSize=40,
.biPlanes=1,
.biCompression=0,
.biXPelsPerMeter=0,
.biYPelsPerMeter=0,
.biClrUsed=0,
.biClrImportant=0,
};
info_h.biWidth = new_width;
info_h.biHeight = new_height;
info_h.biBitCount = bits;
info_h.biSizeImage = new_width*new_height * bits/8;
if(bits == 8) {info_h.biClrUsed=256;}
// ŒÈë™nî^
FILE *pFile = NULL;
// pFile = fopen(name,"wb+");
fopen_s(&pFile, name,"wb+");
if(!pFile) {
perror("Error opening file.");
return;
}
fwrite((char*)&file_h, sizeof(char), sizeof(file_h), pFile);
fwrite((char*)&info_h, sizeof(char), sizeof(info_h), pFile);
// Œ‘Õ{É«±P
if(bits == 8) {
for(unsigned i = 0; i < 256; ++i) {
uch c = i;
fwrite((char*)&c, sizeof(char), sizeof(uch), pFile);
fwrite((char*)&c, sizeof(char), sizeof(uch), pFile);
fwrite((char*)&c, sizeof(char), sizeof(uch), pFile);
fwrite("", sizeof(char), sizeof(uch), pFile);
}
}
// ŒÈëˆDƬÙYÓ<59>
size_t alig = ((new_width*bits/8)*3) % 4;
for(int j = height-1; j >= 0; --j) {
for(unsigned i = 0; i < new_width; ++i) {
uint32_t idx = j*new_width +i;
if(bits == 24) { // RGBˆDƬ
fwrite((char*)&raw_img[idx*3 +2], sizeof(char), sizeof(uch), pFile);
fwrite((char*)&raw_img[idx*3 +1], sizeof(char), sizeof(uch), pFile);
fwrite((char*)&raw_img[idx*3 +0], sizeof(char), sizeof(uch), pFile);
} else if(bits == 8) { // »ÒëAˆD
fwrite((char*)&raw_img[idx], sizeof(char), sizeof(uch), pFile);
}
}
// Œ¦ýR4byte
for(size_t i = 0; i < alig; ++i) {
fwrite("", sizeof(char), sizeof(uch), pFile);
}
}
fclose(pFile);
}
void bmpRead(const char* name, uch** raw_img,
uint32_t* width, uint32_t* height, uint16_t* bits)
{
if(!(name && raw_img && width && height && bits)) {
perror("Error bmpRead.");
return;
}
// ™n°¸ÙYÓ<59>
struct BmpFileHeader file_h;
// ˆDƬÙYÓ<59>
struct BmpInfoHeader info_h;
// ×xÈ¡™nî^
FILE *pFile = NULL;
// pFile = fopen(name, "rb+");
fopen_s(&pFile, name, "rb+");
if(!pFile) {
perror("Error opening file.");
return;
}
fread((char*)&file_h, sizeof(char), sizeof(file_h), pFile);
fread((char*)&info_h, sizeof(char), sizeof(info_h), pFile);
// ×xÈ¡éLŒ
*width = info_h.biWidth;
*height = info_h.biHeight;
*bits = info_h.biBitCount;
size_t ImgSize = ((size_t)*width) * ((size_t)*height) * 3;
*raw_img = (uch*)calloc(ImgSize, sizeof(uch));
// ×xÈ¡×xƬÙYÓ<59>ÞDRAW™nÙYÓ<59>
fseek(pFile, file_h.bfOffBits, SEEK_SET);
size_t alig = ((info_h.biWidth*info_h.biBitCount/8)*3) % 4;
for(int j = *height-1; j >= 0; --j) {
for(unsigned i = 0; i < *width; ++i) {
uint32_t idx = j*(*width)+i;
if(*bits == 24) { // RGBˆDƬ
fread((char*)&(*raw_img)[idx*3 +2], sizeof(char), sizeof(uch), pFile);
fread((char*)&(*raw_img)[idx*3 +1], sizeof(char), sizeof(uch), pFile);
fread((char*)&(*raw_img)[idx*3 +0], sizeof(char), sizeof(uch), pFile);
} else if(*bits == 8) { // »ÒëAˆD
fread((char*)&(*raw_img)[idx], sizeof(char), sizeof(uch), pFile);
}
}
fseek(pFile , (long)alig , SEEK_CUR);
}
fclose(pFile);
}
// ˆDÏñ½Y˜
typedef struct Imgraw {
uint32_t width, height;
uint16_t bits;
uch* data;
} Imgraw;
void Imgraw_Read(const Imgraw* _this, const char* name) {
const Imgraw* p = _this;
bmpRead(name, &p->data, &p->width, &p->height, &p->bits);
}
void Imgraw_Writ(const Imgraw* _this, const char* name, float radio_w, float radio_h) {
const Imgraw* p = _this;
bmpWrite(name, p->data, p->width, p->height, p->bits, radio_w, radio_h);
}
/*==============================================================*/
int main(int argc, char const *argv[]) {
float radio_w, radio_h;
printf("Enter a radio of width :") ;
scanf("%f", &radio_w);
printf("Enter a radio of height :") ;
scanf("%f", &radio_h);
printf("%f :: %f", radio_w, radio_h);
// ½¨˜‹
Imgraw img = {0, 0, 0, NULL};
// ×xˆD
Imgraw_Read(&img, "./input/bw2x1.bmp");
// ŒˆD
Imgraw_Writ(&img, "./output/bw2x1(output).bmp", radio_w, radio_h);
return 0;
}
/*==============================================================*/