c bmp 파일 읽 기
18622 단어 문건
이 코드 에서 파일 헤드 를 직접 읽 는 것 은 잘못된 것 입 니 다. struct 구조 체 메모리 정렬 은 구조 체 끝 에 공간 을 늘 리 는 것 이 아니 라 변수 뒤에 바이트 공간 을 늘 리 는 것 입 니 다.
예 를 들 면:
typedef struct { uint16_t bfType; // 비트 맵 파일 의 형식 은 BM (1 - 2 바이트) uint 32 t bfSize 여야 합 니 다. // 비트 맵 파일 의 크기 는 바이트 단위 (3 - 6 바이트) uint 16 t bfReserved 1; / 비트 맵 파일 보존 자, 0 (7 - 8 바이트) uint 16 t bfReserved 2; / / 비트 맵 파일 보존 자, 0 (9 - 10 바이트) uint 32 t bfOffBits 여야 합 니 다. // 비트 맵 데이터 의 시작 위 치 는 비트 맵 (11 - 14 바이트)} 에 비해 BMPFILEHEADER 입 니 다. 이 구조 체 는 마지막 변수 bfOffBits 가 아 닌 bfType 변수 뒤에 있 습 니 다.
따라서 파일 을 차례로 읽 어야 정확 한 결 과 를 얻 을 수 있다.
#ifndef _BMPLOAD_H_
#define _BMPLOAD_H_
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
//
typedef struct {
int width; //
int height; //
int components; // ,3:24 ,4: alpha 24
unsigned char *data; //
unsigned int unpack_size; //
} TEXTUREIMAGE;
// BMP (14 )
typedef struct {
uint16_t bfType; // , BM(1-2 )
uint32_t bfSize; // , (3-6 )
uint16_t bfReserved1; // , 0(7-8 )
uint16_t bfReserved2; // , 0(9-10 )
uint32_t bfOffBits; // , (11-14 )
} BMPFILEHEADER;
// BMP (40 )
typedef struct {
uint32_t biSize; // (15-18 )
uint32_t biWidth; // , (19-22 )
uint32_t biHeight; // , (23-26 )
uint16_t biPlanes; // , 1(27-28 )
uint16_t biBitCount; // , 1( ),4(16 ),8(256 ) 24( ) (29-30 )
uint32_t biCompression; // , 0( ),1(BI_RLE8 ) 2(BI_RLE4 ) (31-34 )
uint32_t biSizeImage; // , (35-38 )
uint32_t biXPelsPerMeter;// , (39-42 )
uint32_t biYPelsPerMeter;// , (43-46 )
uint32_t biClrUsed; // (47-50 )
uint32_t biClrImportant; // (51-54 )
} BMPINFOHEADER;
#endif
// BMP
int LoadBmp(char *filename, TEXTUREIMAGE *textureImg) {
int i, j;
FILE *file;
BMPFILEHEADER bmpFile;
BMPINFOHEADER bmpInfo;
int pixel_size;
unsigned int unpack_size;
struct stat finfo;
memset(&bmpFile, 0, sizeof bmpFile);
memset(&bmpInfo, 0, sizeof bmpInfo);
memset(textureImg, 0, sizeof (TEXTUREIMAGE));
if (-1 == stat(filename, &finfo)) {
perror("Error to stat");
return -1;
}
//
file = fopen(filename, "rb ");
if (file == NULL) {
perror("Open file error");
return -1;
}
//
fread(&bmpFile.bfType, 2, 1, file);
fread(&bmpFile.bfSize, 4, 1, file);
//
if (finfo.st_size != bmpFile.bfSize) {
printf("file size:%d bmp info size: %d, file not complete!
");
return -1;
}
fread(&bmpFile.bfReserved1, 2, 1, file);
fread(&bmpFile.bfReserved2, 2, 1, file);
fread(&bmpFile.bfOffBits, 4, 1, file);
//printf("bmpFile.bfType:%X
bmpFile.bfSize:%u
bmpFile.bfReserved1:%d
bmpFile.bfReserved2:%d
bmpFile.bfOffBits:%d
", bmpFile.bfType, bmpFile.bfSize, bmpFile.bfReserved1, bmpFile.bfReserved2, bmpFile.bfOffBits);
fread(&bmpInfo, 40, 1, file);
/*
printf("bmpInfo.biSize:%d
", bmpInfo.biSize);
printf("bmpInfo.biWidth:%d
", bmpInfo.biWidth);
printf("bmpInfo.biHeight:%d
", bmpInfo.biHeight);
printf("bmpInfo.biPlanes:%d
", bmpInfo.biPlanes);
printf("bmpInfo.biBitCount:%d
", bmpInfo.biBitCount);
printf("bmpInfo.biCompression:%d
", bmpInfo.biCompression);
printf("bmpInfo.biSizeImage:%d
", bmpInfo.biSizeImage);
printf("bmpInfo.biXPelsPerMeter:%d
", bmpInfo.biXPelsPerMeter);
printf("bmpInfo.biYPelsPerMeter:%d
", bmpInfo.biYPelsPerMeter);
printf("bmpInfo.biClrUsed:%d
", bmpInfo.biClrUsed);
printf("bmpInfo.biClrImportant:%d
", bmpInfo.biClrImportant);
*/
//
if (bmpFile.bfType != 0x4D42) {
printf("File Type Error
");
fclose(file);
return -1;
}
if (bmpInfo.biCompression != 0) {
printf("file compressed!
");
return -1;
}
if (bmpInfo.biBitCount != 24) {
printf("only support 24 bit map
");
fclose(file);
return -1;
}
//
pixel_size = bmpInfo.biBitCount >> 3;
//
unpack_size = bmpInfo.biWidth * bmpInfo.biHeight * pixel_size;
textureImg->data = (unsigned char*) malloc(unpack_size);
if (textureImg->data == NULL) {
fclose(file);
return -1;
}
int bytes_add = bmpInfo.biWidth * pixel_size % 4;
//
for (i = 0; i < bmpInfo.biHeight; i++) {
for (j = 0; j < bmpInfo.biWidth; j++) {
//
fread(
textureImg->data + (i * bmpInfo.biWidth + j) * pixel_size + 2,
sizeof(unsigned char), 1, file);
//
fread(
textureImg->data + (i * bmpInfo.biWidth + j) * pixel_size + 1,
sizeof(unsigned char), 1, file);
//
fread(textureImg->data + (i * bmpInfo.biWidth + j) * pixel_size + 0,
sizeof(unsigned char), 1, file);
// Alpha
if (pixel_size == 4) {
fread(textureImg-> data + (i * bmpInfo.biWidth + j) * pixel_size + 3,
sizeof(unsigned char), 1, file);
}
}
if (bytes_add > 0) { // if pixel_size == 4 then bytes_add == 0
fseek(file, bytes_add, SEEK_CUR);
}
}
//
textureImg->width = bmpInfo.biWidth;
textureImg->height = bmpInfo.biHeight;
textureImg->components = pixel_size;
textureImg->unpack_size = unpack_size;
fclose(file);
return 0;
}
/**
* @brief
* @param[in] jpg_data JPG , unsigned
* @param[in] unpack_size
* @param[in] width JPG
* @param[in] height JPG
* @param[in] components
* @param[in] max_color
* @return max_color 0, , 2,
*/
static int scan_jpg_color(unsigned char *jpg_data, size_t unpack_size, int width, int height, int components, int max_color)
{
if (NULL == jpg_data)
return 0;
register int i, j, pixel, colors = 0;
char *bitHash = (char *) malloc(2 * 1024 * 1024 * sizeof (char));
if (NULL == bitHash) {
perror("malloc error");
return 0;
}
memset(bitHash, 0, 2 * 1024 * 1024 * sizeof (char));
//
for (i=0; i<unpack_size; i+=components) {
pixel = 0;
for (j=0; j<components; j++) {
pixel = (pixel << 8) | jpg_data[i+j];
}
bitHash[pixel / 8] |= 1 << (pixel % 8);
}
for (i=0; i<2*1024*1024*8; i++) {
if (bitHash[i / 8] & (1 << (i % 8))) {
colors++;
if (colors > max_color) {
printf("colors more than %d!
", max_color);
free(bitHash);
return 0;
}
}
}
free(bitHash);
printf("color's count:%d
", colors);
return 2;
}
/**
* @brief , samp
* @param[in] jpg_data JPG , unsigned
* @param[in] width JPG
* @param[in] height JPG
* @param[in] components
* @param[out] samp
* @param[in] pos
* @param[in] num ,
* @return
*/
static int init_pixel_array(unsigned char *jpg_data, int width, int height, int components, int samp[], int pos[][2], int num)
{
int pixel, i, j, k = 0;
size_t pos_num;
for (i=0; i<num; i++) {
if (width < pos[i][0] || height < pos[i][1])
continue; // ,
pos_num = pos[i][1] * width * components + pos[i][0] * components;
pixel = 0;
for (j=0; j<components; j++) { // RGB
pixel = (pixel << 8) | jpg_data[pos_num+j];
}
samp[k] = pixel;
if (k > 0) {
if (samp[k-1] == samp[k]) {
k--;
}
}
k++;
}
return k;
}
#define JPG_SAMP_PIXELS 5
static int scan_jpg_samps(unsigned char *jpg_data, size_t unpack_size, int width, int height, int components, float max_rate)
{
if (NULL == jpg_data)
return 0;
register int i, j, k = 0, m;
register unsigned int pixel;
register unsigned int max_num = max_rate * (unpack_size / 3); //
int samp[JPG_SAMP_PIXELS] = {-1, -1, -1, -1, -1};
int pos[JPG_SAMP_PIXELS][2] = {{0, 0}, {25, 25}, {50, 50}, {(width-1), 0}, {width/2, height/2}};
unsigned int count[JPG_SAMP_PIXELS] = {0};
//size_t pos_num;
//printf("max same pixel:%u
", max_num);
k = init_pixel_array(jpg_data, width, height, components, samp, pos, JPG_SAMP_PIXELS);
//printf("k=%d samp[0] = %X samp[1] = %X samp[2]=%X samp[3] = %X samp[4] = %X
", k, samp[0], samp[1], samp[2], samp[3], samp[4]);
//
for (i=0; i<unpack_size; i+=components) {
pixel = 0;
for (j=0; j<components; j++) {
pixel = (pixel << 8) | jpg_data[i+j];
}
for (m=0; m<k; m++) {
if (pixel == samp[m]) {
count[m]++;
if (count[m] > max_num) {
printf("Spam JPG: [%d] same color's pixel max than %u!
", m, max_num);
return 1;
}
break; // ,
}
}
}
int pixel_num = unpack_size / 3;
for (m=0; m<k; m++) {
printf("Ham JPG: same pixel count[%d] = %u (%f).
", m, count[m], count[m] / (float)pixel_num);
}
return 0;
}
/**
* @brief
* @param[in] jpg_data JPG ,
* @param[in] unpack_size
* @param[in] width JPG
* @param[in] height JPG
* @param[in] components
* @param[in] max_rate
* @param[in] max_color
* @return 0: max_color ; 1: ; 2:
*/
static int scan_jpg_samp_color(unsigned char *jpg_data, size_t unpack_size, int width, int height, int components, float max_rate, int max_color)
{
if (NULL == jpg_data)
return 0;
register int i, j;
register int samp = -1;
register unsigned int pixel;
register unsigned int count = 0;
register int colors = 0;
register unsigned int max_num = max_rate * (unpack_size / 3); //
int pos_x = width-1, pos_y = 0;
size_t pos_num;
//printf("max same pixel:%u
", max_num);
if (components > 3) {
//printf("components=%d return 0!
", components);
return 0;
}
pos_num = pos_y * width * components + pos_x * components;
pixel = 0;
for (j=0; j<components; j++) { // RGB
pixel = (pixel << 8) | jpg_data[pos_num+j];
}
samp = pixel;
// 24 ,2 24 , , 2^24/8=2MB
char *bitHash = (char *) malloc(2 * 1024 * 1024 * sizeof (char));
if (NULL == bitHash) {
perror("malloc error");
return 0;
}
memset(bitHash, 0, 2 * 1024 * 1024 * sizeof (char));
//
//register size_t mid_pos = unpack_size / 3 / 2 * 3;
//register int k;
for (i=0; i<unpack_size; i+=components) {
pixel = 0;
for (j=0; j<components; j++) {
pixel = (pixel << 8) | jpg_data[i+j];
}
if (pixel == samp) {
count++;
if (count > max_num) {
printf("same color's pixel max than %u, Spam JPG!
", max_num);
free(bitHash);
return 1;
}
}
//
bitHash[pixel / 8] |= (1 << (pixel % 8));
/* , , 6%=(1.282-1.202)/1.282 , , 40%
* , 。
if (i == mid_pos) {
colors = 0;
for (k=0; k<2*1024*1024*8; k++) {
if (bitHash[k / 8] & (1 << (k % 8)))
colors++;
if (colors > max_color) {
printf("Ham JPG: colors more than %d!
", max_color);
free(bitHash);
return 0;
}
}
}
*/
}
int pixel_num = unpack_size / 3;
printf("same pixel count = %u(%f)
", count, count / (float)pixel_num);
colors = 0;
for (i=0; i<2*1024*1024*8; i++) {
if (bitHash[i / 8] & (1 << (i % 8))) {
colors++;
if (colors > max_color) {
printf("Ham JPG: colors more than %d!
", max_color);
free(bitHash);
return 0;
}
}
}
free(bitHash);
printf("Spam JPG: color's count:%d
", colors);
return 2;
}
/**
* @brief
* @param[in] jpg_data JPG ,
* @param[in] unpack_size
* @param[in] width JPG
* @param[in] height JPG
* @param[in] components
* @param[in] max_rate
* @param[in] max_color
* @return 0: max_color ; 1: ; 2:
*/
static int scan_jpg_samps_color(unsigned char *jpg_data, size_t unpack_size, int width, int height, int components, float max_rate, int max_color)
{
if (NULL == jpg_data)
return 0;
register int i, j, k = 0, m;
register unsigned int pixel;
register int colors = 0;
register unsigned int max_num = max_rate * (unpack_size / 3); //
int samp[JPG_SAMP_PIXELS] = {-1, -1, -1, -1, -1};
int pos[JPG_SAMP_PIXELS][2] = {{0, 0}, {25, 25}, {50, 50}, {(width-1), 0}, {width/2, height/2}};
unsigned int count[JPG_SAMP_PIXELS] = {0};
//printf("max same pixel:%u
", max_num);
k = init_pixel_array(jpg_data, width, height, components, samp, pos, JPG_SAMP_PIXELS);
//printf("k=%d samp[0] = %X samp[1] = %X samp[2]=%X samp[3] = %X samp[4] = %X
", k, samp[0], samp[1], samp[2], samp[3], samp[4]);
// 24 ,2 24 , , 2^24/8=2MB
char *bitHash = (char *) malloc(2 * 1024 * 1024 * sizeof (char));
if (NULL == bitHash) {
perror("malloc error");
return 0;
}
memset(bitHash, 0, 2 * 1024 * 1024 * sizeof (char));
//
//register size_t mid_pos = unpack_size / 3 / 2 * 3;
//register int k;
for (i=0; i<unpack_size; i+=components) {
pixel = 0;
for (j=0; j<components; j++) {
pixel = (pixel << 8) | jpg_data[i+j];
}
for (m=0; m<k; m++) {
if (pixel == samp[m]) {
count[m]++;
if (count[m] > max_num) {
printf("same color's pixel max than %u, Spam JPG!
", max_num);
free(bitHash);
return 1;
}
}
}
//
bitHash[pixel / 8] |= (1 << (pixel % 8));
/* , , 6%=(1.282-1.202)/1.282 , , 40%
* , 。
if (i == mid_pos) {
colors = 0;
for (k=0; k<2*1024*1024*8; k++) {
if (bitHash[k / 8] & (1 << (k % 8)))
colors++;
if (colors > max_color) {
printf("Ham JPG: colors more than %d!
", max_color);
free(bitHash);
return 0;
}
}
}
*/
}
int pixel_num = unpack_size / 3;
for (m=0; m<k; m++)
printf("same pixel count = %u(%f)
", count[m], count[m] / (float)pixel_num);
colors = 0;
for (i=0; i<2*1024*1024*8; i++) {
if (bitHash[i / 8] & (1 << (i % 8))) {
colors++;
if (colors > max_color) {
printf("Ham JPG: colors more than %d!
", max_color);
free(bitHash);
return 0;
}
}
}
free(bitHash);
printf("Spam JPG: color's count:%d
", colors);
return 2;
}
int main(int argc, char **argv)
{
TEXTUREIMAGE image;
if (0 == LoadBmp( "test.bmp", &image)) {
printf("
");
printf("==============================================
");
scan_jpg_color(image.data, image.unpack_size, image.width, image.height, image.components, 40000);
printf("==============================================
");
scan_jpg_samps(image.data, image.unpack_size, image.width, image.height, image.components, 0.1);
printf("==============================================
");
scan_jpg_samp_color(image.data, image.unpack_size, image.width, image.height, image.components, 0.1, 40000);
printf("==============================================
");
scan_jpg_samps_color(image.data, image.unpack_size, image.width, image.height, image.components, 0.1, 40000);
printf("==============================================
");
free(image.data);
} else {
printf("
");
}
return 0;
}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
python 3 - 파일 수정 - 셸 의 sed 와 유사 한 기능 구현# Auther: Aaron Fan r, ( )。 w, 。【 ; ; ; , 】 a, 。【 ; ; ;】 :f.close() python 。 , str() 。 #r ( ) f = open('yesterday',enc...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.