bmp_v1/try.c

299 lines
11 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>
#include <math.h>
typedef unsigned char uch;
// 妾旀绲愭
#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()
//杈呭姪璁$畻鍑芥暟
float linear_single(float x, float x1, float x2, float f1, float f2){
return floor(f1 * (x2 - x) / (x2 - x1) + f2 * (x - x1) / (x2 - x1));
}
// 鍙岀嚎鎬ф彃鍊煎嚱鏁<E59AB1>
// 鍙傝€<E5829D> https://zh.wikipedia.org/wiki/%E5%8F%8C%E7%BA%BF%E6%80%A7%E6%8F%92%E5%80%BC
char** linear_insert(uch** old_pixels, uint32_t row, uint32_t col, uint32_t old_width, uint32_t old_height, float radio_w, float radio_h){
float x = row / radio_h;
float y = col / radio_w;
// 濡傛灉鏁存暟鏍肩偣灏辩洿鎺ヨ繑鍥<E7B991>
int x1 = floor(x);
int x2 = ceil(x);
int y1 = floor(y);
int y2 = ceil(y);
if (x2 >= old_height){x2 = x1;}
if (y2 >= old_width){y2 = y1;}
if (x1 == x2 && y1 == y2){
uint32_t idx = x1*old_width+y1;
return old_pixels[idx + 0], old_pixels[idx + 1], old_pixels[idx + 2];}
if (x1 == x2){
int x = x1;
uint32_t idx1 = x*old_width+y;
uint32_t idx2 = x*old_width+y;
float r = linear_single(y, y1, y2, old_pixels[x][idx1 + 0], old_pixels[x][idx2 + 0]);
float g = linear_single(y, y1, y2, old_pixels[x][idx1 + 1], old_pixels[x][idx2 + 1]);
float b = linear_single(y, y1, y2, old_pixels[x][idx1 + 2], old_pixels[x][idx2 + 2]);
return (char)r, (char)g, (char)b;
}
if (y1 == y2){
int y = y1;
uint32_t idx = x*old_width+y;
float r = linear_single(x, x1, x2, old_pixels[x1][idx + 0], old_pixels[x2][idx + 0]);
float g = linear_single(x, x1, x2, old_pixels[x1][idx + 1], old_pixels[x2][idx + 1]);
float b = linear_single(x, x1, x2, old_pixels[x1][idx + 2], old_pixels[x2][idx + 2]);
return (char)r, (char)g, (char)b;
}
uint32_t idx1 = x*old_width+y;
uint32_t idx2 = x*old_width+y;
float fy1_r = linear_single(x, x1, x2, old_pixels[x1][idx1 + 0], old_pixels[x2][idx1 + 0]);
float fy1_g = linear_single(x, x1, x2, old_pixels[x1][idx1 + 1], old_pixels[x2][idx1 + 1]);
float fy1_b = linear_single(x, x1, x2, old_pixels[x1][idx1 + 2], old_pixels[x2][idx1 + 2]);
float fy2_r = linear_single(x, x1, x2, old_pixels[x1][idx2 + 0], old_pixels[x2][idx2 + 0]);
float fy2_g = linear_single(x, x1, x2, old_pixels[x1][idx2 + 1], old_pixels[x2][idx2 + 1]);
float fy2_b = linear_single(x, x1, x2, old_pixels[x1][idx2 + 2], old_pixels[x2][idx2 + 2]);
float r = linear_single(y, y1, y2, fy1_r, fy2_r);
float g = linear_single(y, y1, y2, fy1_g, fy2_g);
float b = linear_single(y, y1, y2, fy1_b, fy2_b);
return (char)r, (char)g, (char)b;
}
void bmpWrite(const char* name, const uch* raw_img, uint32_t width, uint32_t height, uint32_t bits, float radio_w, float radio_h){
if(!(name && raw_img)){
perror("Error bmpWrite.");
return;
}
// 妾旀璩囪▕
struct BmpFileHeader file_h = {
.bfTybe=0x4d42,
.bfReserved1=0,
.bfReserved2=0,
.bfOffBits=54,
};
uint32_t new_width = floor(width*radio_w);
uint32_t new_height = floor(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;}
// 鍦栫墖璩囪▕
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;// 澶氬皯浣嶇殑鍦<E6AE91>
info_h.biSizeImage = new_width*new_height * bits/8;
if(bits == 8) {info_h.biClrUsed=256;}
// 瀵叆妾旈牠
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);
// 瀵鑹茬洡
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);
}
}
// char newpixels[new_width*new_height];
unsigned char **newpixels=(unsigned char**)malloc(new_width*new_height*3);// 娌掔敤鍒<E695A4>
// 瀵叆鍦栫墖璩囪▕
size_t alig = ((new_width*bits/8)*3) % 4;
for(int j = new_height-1; j >= 0; --j) {
for(unsigned i = 0; i < new_width; ++i) {
uint32_t idx = j*new_width +i;
if(bits == 24) { // RGB鍦栫墖
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);
// printf("%x",(raw_img)[idx*3 +2]);
// printf("%x",(raw_img)[idx*3 +1]);
// printf("%x",(raw_img)[idx*3 +0]);
// printf(" ");
}
else if(bits == 8) { // 鐏伴殠鍦<E6AEA0>
fwrite((char*)&raw_img[idx], sizeof(char), sizeof(uch), pFile);
}
// printf("\n");
}
// for(int j = new_height-1; j >= 0; --j) {
// for(unsigned i = 0; i < new_width; ++i) {
// uint32_t idx = j*new_width +i;
// if(bits == 24) { // RGB鍦栫墖
// char** r, g, b = linear_insert(&(raw_img), j, i, width, height, radio_w, radio_h);
// fwrite(b, sizeof(char), sizeof(uch), pFile);
// fwrite(g, sizeof(char), sizeof(uch), pFile);
// fwrite(r, sizeof(char), sizeof(uch), pFile);
// } else if(bits == 8) { // 鐏伴殠鍦<E6AEA0>
// fwrite((char*)&raw_img[idx], sizeof(char), sizeof(uch), pFile);
// }
// }
//# 璁畻鏂板儚绱<E5849A>
// 灏嶉綂4byte
for(size_t i = 0; i < alig; ++i) {
fwrite("", sizeof(char), sizeof(uch), pFile);
}
}
fclose(pFile);
free(newpixels); //瑷樺緱閲嬫斁绌洪枔
}
void bmpRead(const char* name, uch** oldpixels, uint32_t* width, uint32_t* height, uint16_t* bits)
{
if(!(name && oldpixels && width && height && bits)) {
perror("Error bmpRead.");
return;
}
// 妾旀璩囪▕
struct BmpFileHeader file_h;
// 鍦栫墖璩囪▕
struct BmpInfoHeader info_h;
// 璁€鍙栨獢闋<E78DA2>
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);
// 璁€鍙栭暦瀵<E69AA6>
*width = info_h.biWidth;
*height = info_h.biHeight;
*bits = info_h.biBitCount;
// **oldpixels=(unsigned char**)malloc((*width)*(*height)*3);
size_t ImgSize = ((size_t)*width) * ((size_t)*height) * 3;
*oldpixels = (uch*)calloc(ImgSize, sizeof(uch));
// 璁€鍙栬畝鐗囪硣瑷婅綁RAW妾旇硣瑷<E7A1A3>
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鍦栫墖
fread((char*)&(*oldpixels)[idx*3 +2], sizeof(char), sizeof(uch), pFile);
fread((char*)&(*oldpixels)[idx*3 +1], sizeof(char), sizeof(uch), pFile);
fread((char*)&(*oldpixels)[idx*3 +0], sizeof(char), sizeof(uch), pFile);
} else if(*bits == 8) { // 鐏伴殠鍦<E6AEA0>
fread((char*)&(*oldpixels)[idx], sizeof(char), sizeof(uch), pFile);
}
}
fseek(pFile , (long)alig , SEEK_CUR);
}
fclose(pFile);
//---------------------------------------------------------------------------
// size_t ImgSize = ((size_t)*width) * ((size_t)*height) * 3;
// *raw_img = (uch*)calloc(ImgSize, sizeof(uch));
// // 璁€鍙栬畝鐗囪硣瑷婅綁RAW妾旇硣瑷<E7A1A3>
// 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鍦栫墖
// 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) { // 鐏伴殠鍦<E6AEA0>
// fread((char*)&(*raw_img)[idx], sizeof(char), sizeof(uch), pFile);
// }
// }
// fseek(pFile , (long)alig , SEEK_CUR);
// }
// fclose(pFile);
//----------------------------------------------------------------------------
for(int j = *height-1; j >= 0; --j) {
for(unsigned i = 0; i < *width; ++i) {
uint32_t idx = j*(*width)+i;
for(int k = 0; k < 3; k++){
printf("%x",(*oldpixels)[idx*3 +k]);
printf(" ");
}
printf("\t");
}
printf("\n");
}
printf("done \n");
}
// 鍦栧儚绲愭
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("\n");
// 寤烘
Imgraw img = {0, 0, 0, NULL};
// 璁€鍦<E282AC>
Imgraw_Read(&img, "./input/bw2x1.bmp");
// 瀵湒
Imgraw_Writ(&img, "./output/bw2x1(output).bmp", radio_w, radio_h);
return 0;
}
/*==============================================================*/