use It8951 files
This commit is contained in:
425
inkycal/display/drivers/parallel_drivers/lib/GUI/GUI_BMPfile.c
Normal file
425
inkycal/display/drivers/parallel_drivers/lib/GUI/GUI_BMPfile.c
Normal file
@@ -0,0 +1,425 @@
|
||||
/*****************************************************************************
|
||||
* | File : GUI_BMPfile.c
|
||||
* | Author : Waveshare team
|
||||
* | Function : Hardware underlying interface
|
||||
* | Info :
|
||||
* Used to shield the underlying layers of each master
|
||||
* and enhance portability
|
||||
*----------------
|
||||
* | This version: V2.0
|
||||
* | Date : 2018-11-12
|
||||
* | Info :
|
||||
* 1.Change file name: GUI_BMP.c -> GUI_BMPfile.c
|
||||
* 2.fix: GUI_ReadBmp()
|
||||
* Now Xstart and Xstart can control the position of the picture normally,
|
||||
* and support the display of images of any size. If it is larger than
|
||||
* the actual display range, it will not be displayed.
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documnetation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS OR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
# THE SOFTWARE.
|
||||
#
|
||||
******************************************************************************/
|
||||
|
||||
#include "GUI_BMPfile.h"
|
||||
#include "GUI_Paint.h"
|
||||
#include "../Config/Debug.h"
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>//exit()
|
||||
#include <string.h>//memset()
|
||||
#include <math.h>//memset()
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
//global variables related to BMP picture display
|
||||
UBYTE *bmp_dst_buf = NULL;
|
||||
UBYTE *bmp_src_buf = NULL;
|
||||
UDOUBLE bmp_width, bmp_height;
|
||||
UBYTE bmp_BitCount;
|
||||
UDOUBLE bytesPerLine;
|
||||
UDOUBLE imageSize;
|
||||
UDOUBLE skip;
|
||||
BMPRGBQUAD palette[256];
|
||||
extern UBYTE isColor;
|
||||
|
||||
static void Bitmap_format_Matrix(UBYTE *dst,UBYTE *src)
|
||||
{
|
||||
UDOUBLE i,j,k;
|
||||
UBYTE *psrc = src;
|
||||
UBYTE *pdst = dst;
|
||||
UBYTE *p = psrc;
|
||||
UBYTE temp;
|
||||
UDOUBLE count;
|
||||
|
||||
//Since the bmp storage is from the back to the front, it needs to be converted in reverse order.
|
||||
switch(bmp_BitCount)
|
||||
{
|
||||
case 1:
|
||||
pdst += (bmp_width * bmp_height);
|
||||
|
||||
for(i=0;i<bmp_height;i++)
|
||||
{
|
||||
pdst -= bmp_width;
|
||||
count = 0;
|
||||
for (j=0;j<(bmp_width+7)/8;j++)
|
||||
{
|
||||
temp = p[j];
|
||||
|
||||
for (k=0;k<8;k++)
|
||||
{
|
||||
pdst[0]= ((temp & (0x80>>k)) >> (7-k));
|
||||
count++;
|
||||
pdst++;
|
||||
if (count == bmp_width)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
pdst -= bmp_width;
|
||||
p += bytesPerLine;
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
pdst += (bmp_width * bmp_height);
|
||||
|
||||
for(i=0;i<bmp_height;i++)
|
||||
{
|
||||
pdst -= bmp_width;
|
||||
count = 0;
|
||||
for (j=0;j<(bmp_width+1)/2;j++)
|
||||
{
|
||||
temp = p[j];
|
||||
pdst[0]= ((temp & 0xf0) >> 4);
|
||||
count++;
|
||||
pdst++;
|
||||
if (count == bmp_width)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
pdst[0] = temp & 0x0f;
|
||||
count++;
|
||||
pdst++;
|
||||
if (count == bmp_width)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
pdst -= bmp_width;
|
||||
p += bytesPerLine;
|
||||
}
|
||||
break;
|
||||
case 8:
|
||||
pdst += (bmp_width*bmp_height);
|
||||
for(i=0;i<bmp_height;i++)
|
||||
{
|
||||
p = psrc+(i+1)*bytesPerLine;
|
||||
p -= skip;
|
||||
for(j=0;j<bmp_width;j++)
|
||||
{
|
||||
pdst -= 1;
|
||||
p -= 1;
|
||||
pdst[0] = p[0];
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 16:
|
||||
pdst += (bmp_width*bmp_height*2);
|
||||
for(i=0;i<bmp_height;i++)
|
||||
{
|
||||
p = psrc+(i+1)*bytesPerLine;
|
||||
p -= skip;
|
||||
for(j=0;j<bmp_width;j++)
|
||||
{
|
||||
pdst -= 2;
|
||||
p -= 2;
|
||||
pdst[0] = p[1];
|
||||
pdst[1] = p[0];
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 24:
|
||||
pdst += (bmp_width*bmp_height*3);
|
||||
for(i=0;i<bmp_height;i++)
|
||||
{
|
||||
p = psrc+(i+1)*bytesPerLine;
|
||||
p -= skip;
|
||||
for(j=0;j<bmp_width;j++)
|
||||
{
|
||||
pdst -= 3;
|
||||
p -= 3;
|
||||
pdst[0] = p[2];
|
||||
pdst[1] = p[1];
|
||||
pdst[2] = p[0];
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 32:
|
||||
pdst += (bmp_width*bmp_height*4);
|
||||
for(i=0;i<bmp_height;i++)
|
||||
{
|
||||
p = psrc+(i+1)*bmp_width*4;
|
||||
for(j=0;j<bmp_width;j++)
|
||||
{
|
||||
pdst -= 4;
|
||||
p -= 4;
|
||||
pdst[0] = p[2];
|
||||
pdst[1] = p[1];
|
||||
pdst[2] = p[0];
|
||||
pdst[3] = p[3];
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void DrawMatrix(UWORD Xpos, UWORD Ypos,UWORD Width, UWORD High,const UBYTE* Matrix)
|
||||
{
|
||||
UWORD i,j,x,y;
|
||||
UBYTE R,G,B;
|
||||
UBYTE temp1,temp2;
|
||||
double Gray;
|
||||
|
||||
for (y=0,j=Ypos;y<High;y++,j++)
|
||||
{
|
||||
for (x=0,i=Xpos;x<Width;x++,i++)
|
||||
{
|
||||
switch(bmp_BitCount)
|
||||
{
|
||||
case 1:
|
||||
case 4:
|
||||
case 8:
|
||||
R = palette[Matrix[(y*Width+x)]].rgbRed;
|
||||
G = palette[Matrix[(y*Width+x)]].rgbGreen;
|
||||
B = palette[Matrix[(y*Width+x)]].rgbBlue;
|
||||
break;
|
||||
|
||||
case 16:
|
||||
temp1 = Matrix[(y*Width+x)*2];
|
||||
temp2 = Matrix[(y*Width+x)*2+1];
|
||||
R = (temp1 & 0x7c)<<1;
|
||||
G = (((temp1 & 0x03) << 3 ) | ((temp2&0xe0) >> 5))<<3;
|
||||
B = (temp2 & 0x1f)<<3;
|
||||
break;
|
||||
|
||||
case 24:
|
||||
R = Matrix[(y*Width+x)*3];
|
||||
G = Matrix[(y*Width+x)*3+1];
|
||||
B = Matrix[(y*Width+x)*3+2];
|
||||
break;
|
||||
|
||||
case 32:
|
||||
R = Matrix[(y*Width+x)*4];
|
||||
G = Matrix[(y*Width+x)*4+1];
|
||||
B = Matrix[(y*Width+x)*4+2];
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
Gray = (R*299 + G*587 + B*114 + 500) / 1000;
|
||||
if(isColor && i%3==2)
|
||||
Paint_SetPixel(i, j, Gray/2);
|
||||
else
|
||||
Paint_SetPixel(i, j, Gray);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
UBYTE GUI_ReadBmp(const char *path, UWORD x, UWORD y)
|
||||
{
|
||||
//bmp file pointer
|
||||
FILE *fp;
|
||||
BMPFILEHEADER FileHead;
|
||||
BMPINFOHEADER InfoHead;
|
||||
UDOUBLE total_length;
|
||||
UBYTE *buf = NULL;
|
||||
UDOUBLE ret = -1;
|
||||
|
||||
fp = fopen(path,"rb");
|
||||
if (fp == NULL)
|
||||
{
|
||||
return(-1);
|
||||
}
|
||||
|
||||
ret = fread(&FileHead, sizeof(BMPFILEHEADER),1, fp);
|
||||
if (ret != 1)
|
||||
{
|
||||
Debug("Read header error!\n");
|
||||
fclose(fp);
|
||||
return(-2);
|
||||
}
|
||||
|
||||
//Detect if it is a bmp image, since BMP file type is "BM"(0x4D42)
|
||||
if (FileHead.bType != 0x4D42)
|
||||
{
|
||||
Debug("It's not a BMP file\n");
|
||||
fclose(fp);
|
||||
return(-3);
|
||||
}
|
||||
|
||||
Debug("*****************************************\n");
|
||||
Debug("BMP_bSize:%d \n", FileHead.bSize);
|
||||
Debug("BMP_bOffset:%d \n", FileHead.bOffset);
|
||||
|
||||
ret = fread((char *)&InfoHead, sizeof(BMPINFOHEADER),1, fp);
|
||||
if (ret != 1)
|
||||
{
|
||||
Debug("Read infoheader error!\n");
|
||||
fclose(fp);
|
||||
return(-4);
|
||||
}
|
||||
|
||||
Debug("BMP_biInfoSize:%d \n", InfoHead.biInfoSize);
|
||||
Debug("BMP_biWidth:%d \n", InfoHead.biWidth);
|
||||
Debug("BMP_biHeight:%d \n", InfoHead.biHeight);
|
||||
Debug("BMP_biPlanes:%d \n", InfoHead.biPlanes);
|
||||
Debug("BMP_biBitCount:%d \n", InfoHead.biBitCount);
|
||||
Debug("BMP_biCompression:%d \n", InfoHead.biCompression);
|
||||
Debug("BMP_bimpImageSize:%d \n", InfoHead.bimpImageSize);
|
||||
Debug("BMP_biXPelsPerMeter:%d \n", InfoHead.biXPelsPerMeter);
|
||||
Debug("BMP_biYPelsPerMeter:%d \n", InfoHead.biYPelsPerMeter);
|
||||
Debug("BMP_biClrUsed:%d \n", InfoHead.biClrUsed);
|
||||
Debug("BMP_biClrImportant:%d \n", InfoHead.biClrImportant);
|
||||
|
||||
total_length = FileHead.bSize-FileHead.bOffset;
|
||||
bytesPerLine=((InfoHead.biWidth*InfoHead.biBitCount+31)>>5)<<2;
|
||||
imageSize=bytesPerLine*InfoHead.biHeight;
|
||||
skip=(4-((InfoHead.biWidth*InfoHead.biBitCount)>>3))&3;
|
||||
|
||||
Debug("bimpImageSize:%d\n", InfoHead.bimpImageSize);
|
||||
Debug("total_length:%d\n", total_length);
|
||||
Debug("bytesPerLine = %d\n", bytesPerLine);
|
||||
Debug("imageSize = %d\n", imageSize);
|
||||
Debug("skip = %d\n", skip);
|
||||
Debug("*****************************************\n");
|
||||
|
||||
bmp_width = InfoHead.biWidth;
|
||||
bmp_height = InfoHead.biHeight;
|
||||
bmp_BitCount = InfoHead.biBitCount;
|
||||
|
||||
//This is old code, but allocate imageSize byte memory is more reasonable
|
||||
bmp_src_buf = (UBYTE*)calloc(1,total_length);
|
||||
//bmp_src_buf = (UBYTE*)calloc(1,imageSize);
|
||||
if(bmp_src_buf == NULL){
|
||||
Debug("Load > malloc bmp out of memory!\n");
|
||||
return -1;
|
||||
}
|
||||
//This is old code, but allocate imageSize byte memory is more reasonable
|
||||
bmp_dst_buf = (UBYTE*)calloc(1,total_length);
|
||||
//bmp_dst_buf = (UBYTE*)calloc(1,imageSize);
|
||||
if(bmp_dst_buf == NULL){
|
||||
Debug("Load > malloc bmp out of memory!\n");
|
||||
return -2;
|
||||
}
|
||||
|
||||
//Jump to data area
|
||||
fseek(fp, FileHead.bOffset, SEEK_SET);
|
||||
|
||||
//Bytes per line
|
||||
buf = bmp_src_buf;
|
||||
while ((ret = fread(buf,1,total_length,fp)) >= 0)
|
||||
{
|
||||
if (ret == 0)
|
||||
{
|
||||
DEV_Delay_us(100);
|
||||
continue;
|
||||
}
|
||||
buf = ((UBYTE*)buf) + ret;
|
||||
total_length = total_length - ret;
|
||||
if(total_length == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
//Jump to color pattern board
|
||||
switch(bmp_BitCount)
|
||||
{
|
||||
case 1:
|
||||
fseek(fp, 54, SEEK_SET);
|
||||
ret = fread(palette,1,4*2,fp);
|
||||
if (ret != 8)
|
||||
{
|
||||
Debug("Error: fread != 8\n");
|
||||
return -5;
|
||||
}
|
||||
|
||||
//this is old code, will likely result in memory leak if use 1bp source bmp image
|
||||
|
||||
bmp_dst_buf = (UBYTE*)calloc(1,InfoHead.biWidth * InfoHead.biHeight);
|
||||
if(bmp_dst_buf == NULL)
|
||||
{
|
||||
Debug("Load > malloc bmp out of memory!\n");
|
||||
return -5;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 4:
|
||||
fseek(fp, 54, SEEK_SET);
|
||||
ret = fread(palette,1,4*16,fp);
|
||||
if (ret != 64)
|
||||
{
|
||||
Debug("Error: fread != 64\n");
|
||||
return -5;
|
||||
}
|
||||
//this is old code, will likely result in memory leak if use 4bp source bmp image
|
||||
|
||||
bmp_dst_buf = (UBYTE*)calloc(1,InfoHead.biWidth * InfoHead.biHeight);
|
||||
if(bmp_dst_buf == NULL)
|
||||
{
|
||||
Debug("Load > malloc bmp out of memory!\n");
|
||||
return -5;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 8:
|
||||
fseek(fp, 54, SEEK_SET);
|
||||
|
||||
ret = fread(palette,1,4*256,fp);
|
||||
|
||||
if (ret != 1024)
|
||||
{
|
||||
Debug("Error: fread != 1024\n");
|
||||
return -5;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
Bitmap_format_Matrix(bmp_dst_buf,bmp_src_buf);
|
||||
DrawMatrix(x, y,InfoHead.biWidth, InfoHead.biHeight, bmp_dst_buf);
|
||||
|
||||
free(bmp_src_buf);
|
||||
free(bmp_dst_buf);
|
||||
|
||||
bmp_src_buf = NULL;
|
||||
bmp_dst_buf = NULL;
|
||||
|
||||
fclose(fp);
|
||||
return(0);
|
||||
}
|
Reference in New Issue
Block a user