/******************************************************************************* Vendor: Xilinx Associated Filename: ap_bmp.cpp Purpose: BMP image reader and writer for AutoESL Revision History: February 13, 2012 - initial release ******************************************************************************* © Copyright 2008 - 2012 Xilinx, Inc. All rights reserved. This file contains confidential and proprietary information of Xilinx, Inc. and is protected under U.S. and international copyright and other intellectual property laws. DISCLAIMER This disclaimer is not a license and does not grant any rights to the materials distributed herewith. Except as otherwise provided in a valid license issued to you by Xilinx, and to the maximum extent permitted by applicable law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND WITH ALL FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY, INCLUDING BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE; and (2) Xilinx shall not be liable (whether in contract or tort, including negligence, or under any other theory of liability) for any loss or damage of any kind or nature related to, arising under or in connection with these materials, including for any direct, or any indirect, special, incidental, or consequential loss or damage (including loss of data, profits, goodwill, or any type of loss or damage suffered as a result of any action brought by a third party) even if such damage or loss was reasonably foreseeable or Xilinx had been advised of the possibility of the same. CRITICAL APPLICATIONS Xilinx products are not designed or intended to be fail-safe, or for use in any application requiring fail-safe performance, such as life-support or safety devices or systems, Class III medical devices, nuclear facilities, applications related to the deployment of airbags, or any other applications that could lead to death, personal injury, or severe property or environmental damage (individually and collectively, "Critical Applications"). Customer assumes the sole risk and liability of any use of Xilinx products in Critical Applications, subject only to applicable laws and regulations governing limitations on product liability. THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE AT ALL TIMES. *******************************************************************************/ #include "vz_ap_bmp.h" #include #include #include #include #include //Open the BMP input file FILE *BMP_InputOpen(char *name){ FILE *bmp_file = fopen(name,"rb"); if(!bmp_file){ printf("ERROR: could not open %s for reading\n",name); return 0; } else return bmp_file; } //Open the BMP output file FILE *BMP_OutputOpen(char *name){ FILE *bmp_file = fopen(name,"wb"); if(!bmp_file){ printf("ERROR: could not open %s for writing\n",name); return NULL; } else return bmp_file; } //Close BMP file int BMP_Close(FILE *bmp_file){ if(bmp_file){ fclose(bmp_file); return 0; } else{ printf("ERROR: could not close %s\n",bmp_file); return 1; } } //Read the BMP file header int BMP_Read_FileHeader(FILE *bmp_file, BMPHeader *file_header){ if(!bmp_file){ printf("ERROR: Can't read the image file\n"); return 1; } if(!fread(file_header,1,14,bmp_file)){ printf("ERROR: Failed to read the image file header \n"); return 1; } else return 0; } //Read the BMP data header int BMP_Read_ImageHeader(FILE *bmp_file, BMPImageHeader *image_header){ if(!bmp_file){ printf("ERROR: Can't read the image file\n"); return 1; } if(!fread(image_header,1,40,bmp_file)){ printf("ERROR: Failed to read the image data header \n"); return 1; } else return 0; } //Read the BMP image data int BMP_Read_Image(FILE *bmp_file, unsigned char *data, int size){ if(!bmp_file){ printf("ERROR: Can't read the image file\n"); return 1; } if(!fread(data,1,size,bmp_file)){ printf("ERROR: Can't read the image data\n"); return 1; } else{ return 0; } } //Blank BMP Image BMPImage *BMP_CreateBlank(void){ BMPImage *bitmap = NULL; BMPHeader *file_header = NULL; BMPImageHeader *image_header = NULL; unsigned char *data; file_header = (BMPHeader *) calloc(sizeof(BMPHeader),1); if(!file_header){ printf("ERROR: Can't create file header in blank BMP\n"); return NULL; } image_header = (BMPImageHeader *) calloc(sizeof(BMPImageHeader),1); if(!image_header){ printf("ERROR: Can't create image header in blank BMP\n"); if(file_header) free(file_header); return NULL; } bitmap = (BMPImage *) malloc(sizeof(BMPImage)); if(!bitmap){ printf("ERROR: Can't create image data in blank BMP\n"); if(file_header) free(file_header); if(image_header) free(image_header); return NULL; } data = (unsigned char *) malloc(MAX_COLS*MAX_ROWS*3); if(!data){ printf("ERROR: Allocate image temp space\n"); if(file_header) free(file_header); if(image_header) free(image_header); if(bitmap) free(bitmap); return NULL; } bitmap->file_header = file_header; bitmap->image_header = image_header; bitmap->data = data; //Initialize to 0 int i, j; for(i = 0; i < MAX_ROWS; i++){ for(j= 0; j < MAX_COLS; j++){ bitmap->R[i][j]=0; bitmap->G[i][j]=0; bitmap->B[i][j]=0; bitmap->Y[i][j]=0; bitmap->U[i][j]=0; bitmap->V[i][j]=0; } } return bitmap; } //Delete bitmap from memory void BMP_Delete(BMPImage *bitmap) { if(bitmap){ if(bitmap->file_header) free(bitmap->file_header); if(bitmap->image_header) free(bitmap->image_header); if(bitmap->data) free(bitmap->data); free(bitmap); } } int readSrcImgPara(char* srcFile, int *OutFrmH, int *OutFrmW) { std::ifstream sw(srcFile); std::string lineData; for(int i=0; i<5; i++) { if(!getline(sw, lineData)) { printf("error: open testIndex file failed!\n"); return 1; } if(i == 4) { sscanf(lineData.c_str(), "%d", OutFrmW); if(*OutFrmW <=0 || *OutFrmW > 1536) { return 2; } } if(i == 5) { sscanf(lineData.c_str(), "%d", OutFrmH); if(*OutFrmH <= 0 || *OutFrmH > 2048) { return 3; } } } return 0; } int readSrcImgFile(char* srcFile, int w, int h, unsigned char* pixDataR, unsigned char* pixDataG, unsigned char* pixDataB) { std::ifstream sw(srcFile); int size = w * h; std::string lineData; int ptr = 0; while(1) { if(!getline(sw, lineData)) { printf("error: open testIndex file failed!\n"); return 1; } int data; sscanf(lineData.c_str(), "%X", &data); pixDataR[ptr] = (unsigned char)data; pixDataG[ptr] = (unsigned char)data; pixDataB[ptr] = (unsigned char)data; ptr++; if(ptr >= size) break; } return 0; } //Read the image int BMP_Read(char *file, int *OutFrmH, int *OutFrmW, unsigned char *R, unsigned char *G, unsigned char *B){ BMPHeader *file_header = NULL; BMPImageHeader *image_header = NULL; unsigned char *image_data = NULL; FILE *bmp_file = NULL; int file_open; bmp_file = BMP_InputOpen(file); if(!bmp_file){ printf("ERROR: Can't open file %s\n",file); return 1; } file_header = (BMPHeader *)malloc(sizeof(BMPHeader)); if(!file_header){ printf("ERROR: Can't allocate memory for file header\n"); return 1; } image_header = (BMPImageHeader *)malloc(sizeof(BMPImageHeader)); if(!image_header){ printf("ERROR: Can't allocate memory for image header\n"); if(file_header) free(file_header); return 1; } int header_read; header_read = BMP_Read_FileHeader(bmp_file,file_header); if(header_read){ printf("ERROR: Can't read the image header\n"); if(file_header) free(file_header); if(image_header) free(image_header); return 1; } int img_header_read; img_header_read = BMP_Read_ImageHeader(bmp_file,image_header); if(img_header_read){ printf("ERROR: Can't read the data header\n"); if(file_header) free(file_header); if(image_header) free(image_header); return 1; } int pixWidth = image_header->BitsPerPixel; int channels; if(pixWidth == 8) channels = 1; else if(pixWidth == 24) channels = 3; else { printf("ERROR: error BMP format, pixWidth=%d\n", pixWidth); if(file_header) free(file_header); if(image_header) free(image_header); return 1; } //Allocate memory for the image pixels int imgSize = image_header->Height * image_header->Width * channels; image_data = (unsigned char *)malloc(imgSize); if(!image_data){ printf("ERROR: Can't allocate memory for the image\n"); if(file_header) free(file_header); if(image_header) free(image_header); return 1; } int img_data_read; if( (channels == 1) && (image_header->Planes == 1) ) BMP_Read_Image(bmp_file,image_data,1024); img_data_read = BMP_Read_Image(bmp_file,image_data,imgSize); if(img_data_read){ printf("ERROR: Can't read the image data\n"); if(file_header) free(file_header); if(image_header) free(image_header); if(image_data) free(image_data); return 1; } int row = (int)image_header->Height; int col = (int)image_header->Width; *OutFrmW = col; *OutFrmH = row; // if(row != (int)image_header->Height){ // printf("ERROR: file image height %i different from requested height %i\n",image_header->Height,row); // if(file_header) free(file_header); // if(image_header) free(image_header); // if(image_data) free(image_data); // return 1; // } // // if(col != (int)image_header->Width){ // printf("ERROR: file image height %i different from requested height %i\n",image_header->Width,col); // if(file_header) free(file_header); // if(image_header) free(image_header); // if(image_data) free(image_data); // return 1; // } unsigned char *linePtr = image_data; //Copy the image data into the storage arrays int i, j; for(i=0; i < row; i++) { linePtr = (unsigned char*)(image_data + i * col * channels); for(j=0; j < col; j++) { // if(i == 1918) // { // int DbgHit = 0; // } unsigned char* tmp = (unsigned char*)(linePtr + j * channels); unsigned char r_temp, b_temp, g_temp; b_temp = *tmp++; if(channels == 3) { g_temp = *tmp++; r_temp = *tmp++; } else { g_temp = b_temp; r_temp = b_temp; } // printf("R %d G %d B %d\n",r_temp,b_temp,g_temp); R[(row-1-i)*col+j] = r_temp; if(G) G[(row-1-i)*col+j] = g_temp; if(B) B[(row-1-i)*col+j] = b_temp; } } BMP_Close(bmp_file); if(file_header) free(file_header); if(image_header) free(image_header); if(image_data) free(image_data); return 0; } //Write the image to a file int BMP_Write(char *file, int row, int col, unsigned char *R, unsigned char *G, unsigned char *B) { // if(row > 2048 && col > 2048) // { // return 0; // } BMPImage *bitmap = NULL; FILE *output_image; unsigned char *data; bitmap = BMP_CreateBlank(); if(!bitmap){ printf("ERROR: Can't create image for output file\n"); return 1; } bitmap->file_header->FileType = 19778; bitmap->file_header->FileSize = 0; bitmap->file_header->Reserved1 = 0; bitmap->file_header->Reserved2 = 0; bitmap->file_header->Offset = 54; bitmap->image_header->Size = 40; bitmap->image_header->Width = col; bitmap->image_header->Height = row; bitmap->image_header->Planes = 1; bitmap->image_header->BitsPerPixel = 24; bitmap->image_header->Compression = 0; bitmap->image_header->SizeOfBitmap = 3*row*col; bitmap->image_header->HorzResolution = 2835; bitmap->image_header->VertResolution = 2835; bitmap->image_header->ColorsUsed = 0; bitmap->image_header->ColorsImportant = 0; data = bitmap->data; //Store the image, bitmaps are stores upside down int i, j; for(i=0; i < row; i++){ for(j=0; j < col; j++){ unsigned char r_temp, g_temp, b_temp; r_temp = R[(row-1-i)*col+j]; g_temp = G[(row-1-i)*col+j]; b_temp = B[(row-1-i)*col+j]; // printf("i %d j %d R %d G %d B %d\n",i, j,r_temp,g_temp,b_temp); *data++ = b_temp; *data++ = g_temp; *data++ = r_temp; } } output_image = fopen(file,"wb"); if(!output_image){ printf("ERROR: Can't open %s for writing\n",file); BMP_Delete(bitmap); return 1; } fwrite(&bitmap->file_header->FileType,1,2,output_image); fwrite(&bitmap->file_header->FileSize,1,4,output_image); fwrite(&bitmap->file_header->Reserved1,1,2,output_image); fwrite(&bitmap->file_header->Reserved2,1,2,output_image); fwrite(&bitmap->file_header->Offset,1,4,output_image); fwrite(&bitmap->image_header->Size,1,4,output_image); fwrite(&bitmap->image_header->Width,1,4,output_image); fwrite(&bitmap->image_header->Height,1,4,output_image); fwrite(&bitmap->image_header->Planes,1,2,output_image); fwrite(&bitmap->image_header->BitsPerPixel,1,2,output_image); fwrite(&bitmap->image_header->Compression,1,4,output_image); fwrite(&bitmap->image_header->SizeOfBitmap,1,4,output_image); fwrite(&bitmap->image_header->HorzResolution,1,4,output_image); fwrite(&bitmap->image_header->VertResolution,1,4,output_image); fwrite(&bitmap->image_header->ColorsUsed,1,4,output_image); fwrite(&bitmap->image_header->ColorsImportant,1,4,output_image); fwrite(bitmap->data,1,bitmap->image_header->Height*bitmap->image_header->Width*3,output_image); fclose(output_image); BMP_Delete(bitmap); return 0; }