STDIO Training

45 bundles
2 files10 days ago
2

class BBmp - C++

class BBmp - C++

Đọc, ghi file Bitmap với C++ - class BBmp.

BBmp.h

1234567891011121314151617181920212223242526272829303132333435#pragma once

#define DATA_OFFSET_OFFSET 0x000A
#define WIDTH_OFFSET 0x0012
#define HEIGHT_OFFSET 0x0016
#define BITS_PER_PIXEL_OFFSET 0x001C
#define HEADER_SIZE 14
#define INFO_HEADER_SIZE 40
#define NO_COMPRESION 0
#define MAX_NUMBER_OF_COLORS 0
#define ALL_COLORS_REQUIRED 0

typedef unsigned int uint32;
typedef short int16;
typedef unsigned char byte;

class BBmp
{
private:
	byte* pixels;
	int width;
	int height;
	int bytesPerPixel;

public:
	BBmp() {
	}

	~BBmp() {
	}

	BBmp(const BBmp& bmp);
	void loadImage(const char* filePath);
	void saveImage(const char* filePath);
};

BBmp.cpp

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <math.h>
#include <string.h>
#include "BBmp.h"

BBmp::BBmp(const BBmp& bmp) {
	int size = bmp.width * bmp.height * bmp.bytesPerPixel;
	pixels = new byte[size];
	memcpy(pixels, bmp.pixels, size);
}

void BBmp::loadImage(const char* filePath) {
	FILE* imageFile = fopen(filePath, "rb");

	uint32 dataOffset;
	fseek(imageFile, DATA_OFFSET_OFFSET, SEEK_SET);
	fread(&dataOffset, 4, 1, imageFile);
	fseek(imageFile, WIDTH_OFFSET, SEEK_SET);
	fread(&this->width, 4, 1, imageFile);
	fseek(imageFile, HEIGHT_OFFSET, SEEK_SET);
	fread(&this->height, 4, 1, imageFile);
	int16 bitsPerPixel;
	fseek(imageFile, BITS_PER_PIXEL_OFFSET, SEEK_SET);
	fread(&bitsPerPixel, 2, 1, imageFile);
	bytesPerPixel = ((uint32)bitsPerPixel) / 8;

	int paddedRowSize = (int)(4 * ceil((float)(width) / 4.0f)) * (bytesPerPixel);
	int unpaddedRowSize = width * bytesPerPixel;
	int totalSize = unpaddedRowSize * height;
	this->pixels = new byte[totalSize];
	int i = 0;
	byte* currentRowPointer = this->pixels + ((height - 1) * unpaddedRowSize);
	for (i = 0; i < height; i++)
	{
		fseek(imageFile, dataOffset + (i * paddedRowSize), SEEK_SET);
		fread(currentRowPointer, 1, unpaddedRowSize, imageFile);
		currentRowPointer -= unpaddedRowSize;
	}

	fclose(imageFile);
}

void BBmp::saveImage(const char* filePath) {
	FILE* outputFile = fopen(filePath, "wb");
	//*****HEADER************//
	const char* BM = "BM";
	fwrite(&BM[0], 1, 1, outputFile);
	fwrite(&BM[1], 1, 1, outputFile);
	int paddedRowSize = (int)(4 * ceil((float)width / 4.0f)) * bytesPerPixel;
	uint32 fileSize = paddedRowSize * height + HEADER_SIZE + INFO_HEADER_SIZE;
	fwrite(&fileSize, 4, 1, outputFile);
	uint32 reserved = 0x0000;
	fwrite(&reserved, 4, 1, outputFile);
	uint32 dataOffset = HEADER_SIZE + INFO_HEADER_SIZE;
	fwrite(&dataOffset, 4, 1, outputFile);

	//*******INFO*HEADER******//
	uint32 infoHeaderSize = INFO_HEADER_SIZE;
	fwrite(&infoHeaderSize, 4, 1, outputFile);
	fwrite(&width, 4, 1, outputFile);
	fwrite(&height, 4, 1, outputFile);
	int16 planes = 1; //always 1
	fwrite(&planes, 2, 1, outputFile);
	int16 bitsPerPixel = bytesPerPixel * 8;
	fwrite(&bitsPerPixel, 2, 1, outputFile);
	//write compression
	uint32 compression = NO_COMPRESION;
	fwrite(&compression, 4, 1, outputFile);
	// write image size(in bytes)
	uint32 imageSize = width * height * bytesPerPixel;
	fwrite(&imageSize, 4, 1, outputFile);
	uint32 resolutionX = 11811; //300 dpi
	uint32 resolutionY = 11811; //300 dpi
	fwrite(&resolutionX, 4, 1, outputFile);
	fwrite(&resolutionY, 4, 1, outputFile);
	uint32 colorsUsed = MAX_NUMBER_OF_COLORS;
	fwrite(&colorsUsed, 4, 1, outputFile);
	uint32 importantColors = ALL_COLORS_REQUIRED;
	fwrite(&importantColors, 4, 1, outputFile);
	int i = 0;
	int unpaddedRowSize = width * bytesPerPixel;
	for (i = 0; i < height; i++)
	{
		int pixelOffset = ((height - i) - 1) * unpaddedRowSize;
		fwrite(&pixels[pixelOffset], 1, paddedRowSize, outputFile);
	}
	fclose(outputFile);
}