ssecorp elpmis elif pmb

 
#define _CRT_SECURE_NO_WARNINGS  // close security warning

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>

 // 建立一個3維動態陣列
void deallocateImgArray(unsigned char ***arr3D,int depth,int height);

// 釋放一個3維動態陣列
unsigned char*** allocateImgArray(int depth,int hegith,int width);

// 分配記憶體給 imgPointer Pair
int allocateImgPtr();

// 釋放 imgPointer Pair記憶體
void releaseImgPtr();

// 開啟來源影像檔案
int openSrcFile( const char* srcName);

// 開啟目的影像檔案
int openDstFile( const char* dstName);

// 關閉 來源影像檔案 和 目的影像檔案
void closeSrcDstFile();

// 初始化BMP影像Header
void initHeaderAndParam();

// 寫入Header到目的檔案
void writeHeaderAndParam();

// 來源影像srcImg 轉為 來源影像陣列
void srcImg2imgArraySrc();

// 目的影像陣列 轉為 目的影像dstImg
void imgArrayDst2dstImg();


// 從原始影像檔案 讀入 BitMap
void InitSrcImgPtr();

void overwrite();
void upsideDown();
void leftRightReverse();
void udlr();

// 建立一個 function ptr table
// 0 : overwrite				原始影像拷貝到目的影像
// 1 : upsideDown				原始影像上下顛倒 輸出 到目的影像
// 2 : leftRightReverse			原始影像左右顛倒 輸出 到目的影像
// 3 : udlr						原始影像上下左右顛倒 輸出 到目的影像
void (* operation[])() = { overwrite, upsideDown, leftRightReverse, udlr };


FILE *srcFile = NULL;				// src file pointer
FILE *dstFile = NULL;				// dst file pointer

unsigned int width=0,height=0;		// 影像寬,影像高
unsigned char* srcImg = NULL;		// 以byte操作的原始影像pointer
unsigned char* dstImg = NULL;		// 以byte操作的目的影像pointer

unsigned char ***imgArraySrc=NULL;	// 以下標[]操作的原始影像矩陣
unsigned char ***imgArrayDst=NULL;	// 以下標[]操作的目的影像矩陣
unsigned char header[54]=
{
	0x42,			// Byte 0 , ID : 'B' as a character
	0x4d,			// Byte 1 , ID : 'M' as a character
	0, 0, 0, 0,		// Byte 2 ~ 5 , fileSize
	0, 0,			// Byte 6 ~ 7 , reserved1 field
	0, 0,			// Byte 8 ~ 9 , reserved2 field
	54, 0, 0, 0,	// Byte 10~ 13, header offset in byte
	40, 0, 0, 0,	// Byte 14~ 17, bitmap info header size in byte
	0, 0, 0, 0,		// Byte 18~ 21, bmp width
	0, 0, 0, 0,		// Byte 22~ 25, bmp height
	1, 0,			// Byte 26~ 27, pixel plannes number, set to 1 forever
	0, 0,			// Byte 28~ 29, Bit per pixel 24 or 32
	0, 0, 0, 0,		// Byte 30~ 33, Compression
	0, 0, 0, 0,		// Byte 34~ 37, bim map size in byte
	0, 0, 0, 0,		// Byte 38~ 41, horizontal resolution
	0, 0, 0, 0,		// Byte 42~ 45, vertical resolution
	0, 0, 0, 0,		// Byte 46~ 49, used colors
	0, 0, 0, 0		// Byte 50~ 53, important colors
	};

	unsigned int fileSize=0;			// mapping Byte 2 ~ 6 , total 4 byte width
	unsigned int imageArraySize=0;		// imageArraySize
	unsigned int rgbRawDataOffset=0;	// mapping Byte 10 ~ 13 , total 4 byte width
	unsigned short bitPerPixel=0;		// mapping Byte 28 ~ 29, total 2 byte width, record the bit mode used, 24 or 32
	unsigned short bytePerPixel=0;		// record the pixel byte constant = bitPerPixel / 8
	unsigned int rowSize = 0;			// record the rowsize after padding

// 上下顛倒
void upsideDown()
{
	for(int y = 0; y != height; ++y) {
		for(int x = 0; x != width; ++x) {
			unsigned int newYpos = height - 1 - y;				// change y coordinate   
			imgArrayDst[ 2 ][ y ][ x ] = imgArraySrc[ 2 ][ newYpos ][ x ];
			imgArrayDst[ 1 ][ y ][ x ] = imgArraySrc[ 1 ][ newYpos ][ x ];
			imgArrayDst[ 0 ][ y ][ x ] = imgArraySrc[ 0 ][ newYpos ][ x ];
		}
   }   
	return;
}//end of function upsideDown

// 左右顛倒
void leftRightReverse()
{
	for(int y = 0; y != height; ++y) {
		for(int x = 0; x != width; ++x) {
			unsigned int newXpos = width - 1 - x;				// change x coordinate   
			imgArrayDst[ 2 ][ y ][ x ] = imgArraySrc[ 2 ][ y ][ newXpos ];
			imgArrayDst[ 1 ][ y ][ x ] = imgArraySrc[ 1 ][ y ][ newXpos ];
			imgArrayDst[ 0 ][ y ][ x ] = imgArraySrc[ 0 ][ y ][ newXpos ];
		}
   }   
	return;
}//end of function leftRightReverse

// 上下左右顛倒
void udlr()
{
	for(int y = 0; y != height; ++y) {
		for(int x = 0; x != width; ++x) {
			unsigned int newXpos = width - 1 - x;				// change x coordinate   
			unsigned int newYpos = height - 1 - y;				// change x coordinate   
			imgArrayDst[ 2 ][ y ][ x ] = imgArraySrc[ 2 ][ newYpos ][ newXpos ];
			imgArrayDst[ 1 ][ y ][ x ] = imgArraySrc[ 1 ][ newYpos ][ newXpos ];
			imgArrayDst[ 0 ][ y ][ x ] = imgArraySrc[ 0 ][ newYpos ][ newXpos ];
		}
   }   
	return;
}//end of function leftRightReverse

// 純粹覆寫
void overwrite()
{
	for(int y = 0; y != height; ++y) {	
		for(int x = 0; x != width; ++x) {
			imgArrayDst[ 2 ][ y ][ x ] = imgArraySrc[ 2 ][ y ][ x ];
			imgArrayDst[ 1 ][ y ][ x ] = imgArraySrc[ 1 ][ y ][ x ];
			imgArrayDst[ 0 ][ y ][ x ] = imgArraySrc[ 0 ][ y ][ x ];	
		}
   }   
	return;
}//end of function leftRightReverse

// 開啟來源影像檔案
int openSrcFile( const char* srcName)
{
	
	// "R"ead bit map file in "B"inary mode
	srcFile = fopen(srcName,"rb");		
	if( srcFile == NULL )
	{
		printf("could not open source bmp file.");
		return -1;
	}
	return 0;
}//end of openSrcFile

// 開啟目的影像檔案
int openDstFile( const char* dstName)
{
	// "W"rite bit map file in "B"inary mode
	dstFile = fopen(dstName,"wb");		
	if( dstFile == NULL )
	{
		printf("could not open dst file.");
		return -1;
	}
	return 0;
}//end of openDstFile

void closeSrcDstFile()
{
	// close input file stream
	fclose(srcFile);
	// close output file stream
	fclose(dstFile);
	return;
}//end of function closeSrcDstFile

void initHeaderAndParam()
{
	// move offset to 10th byte to get rgb raw data offset
	fseek( srcFile, 10, SEEK_SET);
	fread( &rgbRawDataOffset, sizeof(unsigned int), 1, srcFile);	// read 1 byte from byte 10 to get header offset

	// move offset to 18 to get width and height
	fseek( srcFile, 18, SEEK_SET);
	fread( &width, sizeof(unsigned int), 1, srcFile);					// read 4 byte from byte 18 ~ 21 to get image width
	fread( &height, sizeof(unsigned int), 1, srcFile);					// read 4 byte from byte 22 ~ 25 to get image height

	// move offsetto 28 to get bitPerPixel
	fseek( srcFile, 28, SEEK_SET);
	fread( &bitPerPixel, sizeof(unsigned short), 1, srcFile);	// read 4 byte from byte 28 ~ 29 to get bitPerPixel
	
	// 知道 bitPerPixel 之後,換算成 bytePerPixel
	bytePerPixel = bitPerPixel / 8 ;

	// 知道 bitPerPixel 和 width之後,計算 rowSize
	rowSize = (  ( bitPerPixel * width+ 31 )/32  ) * 4  ;		// take padding into consideration

	// 知道 height 和 rowSzie 計算 imageArraySize
	imageArraySize = height * rowSize;

	// 知道 height 和 rowSzie 還有 rgbRawDataOffset 之後,計算整個BMP file大小(包含Header)
	fileSize = imageArraySize + rgbRawDataOffset;				// 影像高 * 每一列的byteSize + rgbRawDataOffset


	return;
}//end of initHeaderAndParam

void writeHeaderAndParam()
{
	// write Default header to dstFile from byte 0
	fwrite( header, sizeof(unsigned char), rgbRawDataOffset, dstFile);
	
	// modify dstFile's header start

	fseek( dstFile, 2, SEEK_SET);		// move offset to 2nd byte to write bmp file size
    fwrite( &fileSize, sizeof(unsigned int),1, dstFile);
	
	fseek( dstFile, 18, SEEK_SET);		// move offset to 18th byte to write bit map Width
	fwrite( &width, sizeof(unsigned int),1, dstFile);
	
	fseek( dstFile, 22, SEEK_SET);		// move offset to 22th byte to write bit map Height
	fwrite( &height, sizeof(unsigned int),1, dstFile);
	
	fseek( dstFile, 28, SEEK_SET);		// move offset to 28th byte to write bitPerPixel
	fwrite( &bitPerPixel, sizeof(unsigned short),1, dstFile);
	return;
}//end of writeHeaderAndParam

int allocateImgPtr()
{
	// allocate memory space for srcImg pointer	
	srcImg = (unsigned char *)malloc(  (size_t) imageArraySize );

	if( srcImg == NULL )
	{
		printf("malloc srcImge Error");
		return -1;
	}

	// allocate memory space for dstImg pointer
	dstImg = (unsigned char *)malloc(  (size_t) imageArraySize );
	if( dstImg == NULL )
	{
		printf("malloc dstImge Error");
		return -1;
	}

	return 0;
}//end of allocateImgPtr

void releaseImgPtr()
{
	// release srcImg memory space
	free( srcImg );
	// release dstImg memory space
	free( dstImg );
	return;
}//end of releaseImgPtr


void rawCopyImgPtr()
{	
	//
	// RAW COPY scrImg to dstImg
	//memcpy(dstImg, srcImg, (size_t) height * rowSize );
	//
	return;
}//end of rawCopyImgPtr

void InitSrcImgPtr()
{
	// move offset to rgbRawDataOffset to get RGB image array
	fseek(srcFile, rgbRawDataOffset, SEEK_SET);
	// copy pixel array from srcFile to scrImg
	fread(srcImg, sizeof(unsigned char), (size_t) imageArraySize, srcFile );
	
	return;
}//end of InitSrcImgPtr

void writeDstImgPtr()
{	
	fseek( dstFile, 54, SEEK_SET);		// move offset to 54th byte for writing dstImg to dstFile
	// write image
	//                           注意:此處大小應為 imageArraySize = height * rowSize
	fwrite(dstImg, sizeof(unsigned char),(size_t)imageArraySize, dstFile);	
	return;
}//end of writeDstImgPtr

//allocate a Color Map
unsigned char*** allocateImgArray(int depth,int h,int w)
{
	unsigned char ***arr3D=NULL;
	int i=0,j=0,k=0;

	arr3D = (unsigned char***)malloc(depth * sizeof(unsigned char **));

	for(i=0;i<depth;i++)
	{
		arr3D[i] = (unsigned char**)malloc(h * sizeof(char*));
		for(j=0;j<h;j++)
		{
			arr3D[i][j] = (unsigned char*)malloc(w*sizeof(char));
		}
	}
	

	for( i = 0 ; i < depth ; ++i )
	{
		for( j = 0 ; j < h ; ++j )
		{
			for( k = 0 ; k < w ; ++k )
			{
				//printf("%c \n", arr3D[i][j][k]);
				arr3D[i][j][k]=(unsigned char)'0';
				//printf("%c \n", arr3D[i][j][k]);
			}
		}
	}
	return arr3D;
}//End of allocateImgArray

//Deallocate Color Map
void deallocateImgArray(unsigned char ***arr3D,int depth,int height)
{
    int i,j;

    for(i=0;i<depth;i++)
    {
    	for(j=0;j<height;j++)
    	{
    		free(arr3D[i][j]);
    	}
    	free(arr3D[i]);
    }
    free(arr3D);
}//end of deallocateImgArray

// 來源影像 轉為 來源影像陣列
void srcImg2imgArraySrc()
{
	// srcImg 轉 imgArraySrc
	for(int y = 0; y != height; ++y) {
		for(int x = 0; x != width; ++x) {
			 imgArraySrc[2][y][x] = *(srcImg + rowSize * y + x*bytePerPixel + 2);	// Red channel
			 imgArraySrc[1][y][x] = *(srcImg + rowSize * y + x*bytePerPixel + 1);	// Green channel
			 imgArraySrc[0][y][x] = *(srcImg + rowSize * y + x*bytePerPixel + 0);	// Blue channel
		 }
    }   
	return ;
}//end of function srImg2imgArraySrc

// 目的影像陣列 轉為 目的影像
void imgArrayDst2dstImg()
{
	// imgArrayDst 轉 dstImg
	for(int y = 0; y != height; ++y) {
		for(int x = 0; x != width; ++x) {
			 *(dstImg + rowSize * y + x*bytePerPixel + 2) = imgArrayDst[2][y][x];	// Red channel
			 *(dstImg + rowSize * y + x*bytePerPixel + 1) = imgArrayDst[1][y][x];	// Green channel
			 *(dstImg + rowSize * y + x*bytePerPixel + 0) = imgArrayDst[0][y][x];	// Blue channel
		}
	}   
	return ;
}//end of function imgArrayDst2dstImg


int process( const char *srcName, const char *dstName, const int ch)
{
	if( openSrcFile( srcName) == -1 ) return -1;
	openSrcFile( srcName);			// 讀取原始影像檔案
	initHeaderAndParam();			// 處始化BMP影像參數
	allocateImgPtr();				// 分配記憶體給 影像指標
	InitSrcImgPtr();				// 從原始影像檔案 讀入 BitMap 到  來源影像srcImg
	
	imgArraySrc = allocateImgArray( 3, height, width);	// 替 imgArraySrc 分配空間
	imgArrayDst = allocateImgArray( 3, height, width);	// 替 imgArrayDst 分配空間

	srcImg2imgArraySrc();			// 來源影像srcImg 轉為 來源影像陣列 imgArraySrc

    // 針對imgArraySrc 和 imgArrayDst 作運算處理,透過 ch 選擇
	operation[ch]();

	imgArrayDst2dstImg();			// 目的影像陣列 imgArrayDst 轉為 目的影像dstImg
	
   
	deallocateImgArray(imgArraySrc,3,height);	// 釋放 imgArraySrc
	deallocateImgArray(imgArrayDst,3,height);	// 釋放 imgArrayDst
	
	openDstFile(dstName);		// 開啟目的影像檔案

	writeHeaderAndParam();		// 寫入Header到目的檔案
	writeDstImgPtr();			// 把目的影像dstImg 輸出 Bitmap 到 目的影像檔案

	releaseImgPtr();			// 釋放 imgPointer Pair記憶體
	closeSrcDstFile();			// 關閉 來源影像檔案 和 目的影像檔案

	return 0;
}//end of readWrite



int main()
{	
	char inputFilename[128]={0};
	char outputFilename[128]={0};
	int choice = 0;
	printf("please input filename to load.\n");
	scanf("%s",inputFilename);	
	strcpy(outputFilename,inputFilename);
	strcat(inputFilename,".bmp");
	strcat(outputFilename,"Output.bmp");

	printf("\n\nplease intput the procedure you want to carry out\n"
			"0. copy\n"
			"1. upside down\n"
			"2. left-right reverse\n"
			"3. upside down and left-right reverse\n");
	scanf("%d",&choice);
	process(inputFilename, outputFilename, choice);

	return 0;
}//end of main





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值