#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "public.h"
#include "fbdev.h"
#include "gdi.h"
#include "jpeglib.h"
#include "jerror.h"
static unsigned short RGB2LCD16BitsColor(HCANVAS hCanvas,St_RGB stColor)//给画布设年色置
{
St_Canvas *pstCanvas = hCanvas;
unsigned int uiBitsPerPixel = 0;
unsigned int uiRedLen = 0,uiGreenLen = 0,uiBlueLen = 0;
unsigned int uiRedOff = 0,uiGreenOff = 0,uiBlueOff = 0;
unsigned short usRed = 0,usGreen = 0,usBlue = 0;
unsigned short us16BitsColor = 0;
if(NULL == pstCanvas)
{
printf(DEBUG_ERROR"in file:%s:%d:Invalid Canvas!!!\n",__FILE__,__LINE__);
return 0;
}
if(NULL == pstCanvas->hLCDDev)
{
printf(DEBUG_ERROR"in file:%s:%d:Invalid Canvas!!!\n",__FILE__,__LINE__);
return 0;
}
uiBitsPerPixel = GetBitsPerPixel(pstCanvas->hLCDDev);
if(uiBitsPerPixel != 16)
{
printf(DEBUG_ERROR"in file:%s:%d:Invalid BitsPerPixel:%d!!!\n",
__FILE__,__LINE__,(int)uiBitsPerPixel);
return 0;
}
uiRedLen = GetColorLength(pstCanvas->hLCDDev,E_RED);
uiGreenLen = GetColorLength(pstCanvas->hLCDDev,E_GREEN);
uiBlueLen = GetColorLength(pstCanvas->hLCDDev,E_BLUE);
uiRedOff = GetColorOffset(pstCanvas->hLCDDev,E_RED);
uiGreenOff = GetColorOffset(pstCanvas->hLCDDev,E_GREEN);
uiBlueOff = GetColorOffset(pstCanvas->hLCDDev,E_BLUE);
usRed = stColor.ucRed;
usGreen = stColor.ucGreen;
usBlue = stColor.ucBlue;
us16BitsColor = ((usRed>>(8-uiRedLen)) << uiRedOff)
| ((usGreen>>(8-uiGreenLen)) << uiGreenOff)
| ((usBlue>>(8-uiBlueLen)) << uiBlueOff);
return us16BitsColor;
}
void DrawAPoint(HCANVAS hCanvas,int x,int y,St_RGB stColor)
{
St_Canvas *pstCanvas = hCanvas;
unsigned int uiLCDWidth = 0;
unsigned int uiLCDHeight = 0;
unsigned short usColor16b = 0;
unsigned short * pusStartBuf = NULL;
if(NULL == pstCanvas)//画布如果为空
{
printf(DEBUG_ERROR"in file:%s:%d:Invalid Canvas!!!\n",__FILE__,__LINE__);//标柱在哪里出错
return;
}
if(NULL == pstCanvas->hLCDDev)//如果LED设备不存在
{
printf(DEBUG_ERROR"in file:%s:%d:Invalid LCD Device!!!\n",__FILE__,__LINE__);
return;
}
usColor16b = RGB2LCD16BitsColor(hCanvas,stColor);//设置16为颜色bit位
uiLCDWidth = GetLCDWidth(pstCanvas->hLCDDev);//获得设备画布的长度和高度
uiLCDHeight = GetLCDHeight(pstCanvas->hLCDDev);
if(x < 0 || x >= uiLCDWidth || y < 0 || y >= uiLCDHeight)//判断要画的点的位置是否在范围之内
{
printf(DEBUG_WARNING"in file:%s:%d:Invalid value of point:(%d,%d)!!!\n",
__FILE__,__LINE__,x,y);
return;
}
pusStartBuf = (unsigned short *)pstCanvas->pvCanvasBuf;//找到起始位置
*(pusStartBuf + uiLCDWidth * y + x) = usColor16b;//找到要画的点的存放颜色的位置,然后赋值
return;
}
void FillRect(HCANVAS hCanvas,int x,int y,int w,int h,St_RGB stColor)
{
St_Canvas *pstCanvas = hCanvas;
unsigned int uiLCDWidth = 0;
unsigned int uiLCDHeight = 0;
unsigned short usColor16b = 0;
unsigned short * pusStartBuf = NULL;
unsigned short * pusRowData = NULL;
int i = 0;
unsigned int uiNumOfPixelPerHLine = 0;
unsigned int uiNumOfPixelPerVLine = 0;
if(NULL == pstCanvas)
{
printf(DEBUG_ERROR"in file:%s:%d:Invalid Canvas!!!\n",__FILE__,__LINE__);
return;
}
if(NULL == pstCanvas->hLCDDev)
{
printf(DEBUG_ERROR"in file:%s:%d:Invalid LCD Device!!!\n",__FILE__,__LINE__);
return;
}
usColor16b = RGB2LCD16BitsColor(hCanvas,stColor);
uiLCDWidth = GetLCDWidth(pstCanvas->hLCDDev);
uiLCDHeight = GetLCDHeight(pstCanvas->hLCDDev);
if(x < 0 || x >= uiLCDWidth
|| y < 0 || y >= uiLCDHeight
|| w <= 0 || h <= 0)
{
printf(DEBUG_WARNING"in file:%s:%d:Invalid value of point:(%d,%d),w=%d,h=%d!!!\n",
__FILE__,__LINE__,x,y,w,h);
return;
}
uiNumOfPixelPerHLine = MIN(uiLCDWidth-x,w);
pusRowData = (unsigned short *)malloc(uiNumOfPixelPerHLine*sizeof(unsigned short));
if(NULL == pusRowData)
{
printf(DEBUG_WARNING"in file:%s:%d:Malloc failed!!!\n",__FILE__,__LINE__);
return;
}
for(i = 0;i < uiNumOfPixelPerHLine;i++)
{
pusRowData[i] = usColor16b;
}
uiNumOfPixelPerVLine = MIN(uiLCDHeight-y,h);
pusStartBuf = (unsigned short *)pstCanvas->pvCanvasBuf;
for(i = 0;i < uiNumOfPixelPerVLine;i++)
{
memcpy(pusStartBuf + (y+i)*uiLCDWidth + x,
pusRowData,
uiNumOfPixelPerHLine*sizeof(unsigned short));
}
free(pusRowData);
return;
}
void DrawText(HCANVAS hCanvas,
const unsigned char *pucFontData,
int wFont,int hFont,
int x,int y,
St_RGB stColor)//x,y代表着起始坐标
{
int i,j;
St_Canvas *pstCanvas = hCanvas;
unsigned int uiLCDWidth = 0;
unsigned int uiLCDHeight = 0;
unsigned short usColor16b = 0;
unsigned short * pusStartBuf = NULL;
if(NULL == pstCanvas)//画布如果为空
{
printf(DEBUG_ERROR"in file:%s:%d:Invalid Canvas!!!\n",__FILE__,__LINE__);//标柱在哪里出错
return;
}
if(NULL == pstCanvas->hLCDDev)//如果LED设备不存在
{
printf(DEBUG_ERROR"in file:%s:%d:Invalid LCD Device!!!\n",__FILE__,__LINE__);
return;
}
usColor16b = RGB2LCD16BitsColor(hCanvas,stColor);//设置16为颜色bit位
uiLCDWidth = GetLCDWidth(pstCanvas->hLCDDev);//获得设备画布的长度和高度
uiLCDHeight = GetLCDHeight(pstCanvas->hLCDDev);
if(x < 0 || x >= uiLCDWidth || y < 0 || y >= uiLCDHeight)//判断要画的点的位置是否在范围之内
{
printf(DEBUG_WARNING"in file:%s:%d:Invalid value of point:(%d,%d)!!!\n",
__FILE__,__LINE__,x,y);
return;
}
pusStartBuf = (unsigned short *)pstCanvas->pvCanvasBuf;//找到起始位置
for(i=0;i<3*24;i=i+3)
{
//每三个是一行是否要图颜色位的标志
//0-》0 1 2 3 4 5 6 7
// pucFontData[i]
for(j=0;j<8;j++)
{
if(pucFontData[i] &(unsigned char)(((unsigned char)0x01)<<j))
{
DrawAPoint(hCanvas,x+j,y+i/3,stColor);
}
}
//pucFontData[i+1]
//1-》8 9 10 11 12 13 14 15
for(j=0;j<8;j++)
{
if(pucFontData[i+1] &(unsigned char)(((unsigned char)0x01)<<j))
{
DrawAPoint(hCanvas,x+j+8,y+i/3,stColor);
}
}
//pucFontData[i+2]
//2-》16 17 18 19 20 21 22 23
for(j=0;j<8;j++)
{
if(pucFontData[i+2] &(unsigned char)(((unsigned char)0x01)<<j))
{
DrawAPoint(hCanvas,x+j+16,y+i/3,stColor);
}
}
}
//如将十六进制数转换成二进制数,只要将每一位十六进制数用四位相应的二进制数表示,即可完成转换
return;
}
void DrawBmp(HCANVAS hCanvas,
const char * pstrBMPFileName,
int wBMP,int hBMP,
int x,int y)
{
St_Canvas *pstCanvas = hCanvas;
int i,j;
FILE *pfBMP=NULL;
int iRGBDataoffset=0;
unsigned char * pucLineData=NULL;
St_RGB stColor={0};
unsigned int uiLCDWidth = 0;
unsigned int uiLCDHeight = 0;
// unsigned short usColor16b = 0;
// unsigned short * pusStartBuf = NULL;
if(NULL == pstCanvas)//画布如果为空
{
printf(DEBUG_ERROR"in file:%s:%d:Invalid Canvas!!!\n",__FILE__,__LINE__);//标柱在哪里出错
return;
}
if(NULL==pstrBMPFileName)
{
printf(DEBUG_ERROR"in file:%s:%d:Invalid BMP File Name!!!\n",__FILE__,__LINE__);//标柱在哪里出错
return;
}
if(NULL == pstCanvas->hLCDDev)//如果LED设备不存在
{
printf(DEBUG_ERROR"in file:%s:%d:Invalid LCD Device!!!\n",__FILE__,__LINE__);
return;
}
// usColor16b = RGB2LCD16BitsColor(hCanvas,stColor);//设置16为颜色bit位
uiLCDWidth = GetLCDWidth(pstCanvas->hLCDDev);//获得设备画布的长度和高度
uiLCDHeight = GetLCDHeight(pstCanvas->hLCDDev);
if(x < 0 || x >= uiLCDWidth || y < 0 || y >= uiLCDHeight)//判断要画的点的位置是否在范围之内
{
printf(DEBUG_WARNING"in file:%s:%d:Invalid value of point:(%d,%d)!!!\n",
__FILE__,__LINE__,x,y);
return;
}
//pusStartBuf = (unsigned short *)pstCanvas->pvCanvasBuf;//找到起始位置
pucLineData=(unsigned char *)malloc(wBMP*3);
if(NULL == pucLineData)
{
printf(DEBUG_ERROR"in file:%s:%d:Malloc failed!!!\n",
__FILE__,__LINE__);
return;
}
pfBMP=fopen(pstrBMPFileName,"rb");
if(NULL == pfBMP)
{
printf(DEBUG_ERROR"in file:%s:%d:Can't open BMP File:%s!!!\n",
__FILE__,__LINE__,pstrBMPFileName);
return;
}
fseek(pfBMP,10,SEEK_SET);
fread(&iRGBDataoffset,4,1,pfBMP);
fseek(pfBMP,iRGBDataoffset,SEEK_SET);
for(i=0;i<hBMP;i++)
{
fread(pucLineData,1,wBMP*3,pfBMP);
for(j = 0;j < wBMP;j++)
{
stColor.ucBlue = pucLineData[j*3];
stColor.ucGreen = pucLineData[j*3+1];
stColor.ucRed = pucLineData[j*3+2];
DrawAPoint(hCanvas,x+j,y+hBMP-1-i,stColor);
}
}
free(pucLineData);
pucLineData=NULL;
fclose(pfBMP);
pfBMP=NULL;
return;
}
void DrawJPG(HCANVAS hCanvas,
const char * pstrJPGFileName,
int x,int y)
{
St_Canvas *pstCanvas = hCanvas;
unsigned int uiLCDWidth = 0;
unsigned int uiLCDHeight = 0;
int i = 0;
FILE * pfJPG = NULL;
JSAMPARRAY ppucRowData = NULL;
St_RGB stColor = {0};
struct jpeg_decompress_struct jinfo;
struct jpeg_error_mgr jerr;
unsigned int row_stride = 0;
unsigned long uiRealWidth = 0;
unsigned long uiRealHeight = 0;
if(NULL == pstCanvas)
{
printf(DEBUG_ERROR"in file:%s:%d:Invalid Canvas!!!\n",__FILE__,__LINE__);
return;
}
if(NULL == pstCanvas->hLCDDev)
{
printf(DEBUG_ERROR"in file:%s:%d:Invalid LCD Device!!!\n",__FILE__,__LINE__);
return;
}
if(NULL == pstrJPGFileName)
{
printf(DEBUG_ERROR"in file:%s:%d:Invalid BMP File Name!!!\n",
__FILE__,__LINE__);
return;
}
uiLCDWidth = GetLCDWidth(pstCanvas->hLCDDev);
uiLCDHeight = GetLCDHeight(pstCanvas->hLCDDev);
if(x < 0 || x >= uiLCDWidth
|| y < 0 || y >= uiLCDHeight)
{
printf(DEBUG_WARNING"in file:%s:%d:Invalid value of point:(%d,%d)!!!\n",
__FILE__,__LINE__,x,y);
return;
}
/*Bind error handler*/
jinfo.err = jpeg_std_error(&jerr);
/*init jpeg decompress object*/
jpeg_create_decompress(&jinfo);
/*Bind jpg data object*/
pfJPG = fopen(pstrJPGFileName,"rb");
if(NULL == pfJPG)
{
printf(DEBUG_WARNING"in file:%s:%d:Open file:%s failed!!!\n",
__FILE__,__LINE__,pstrJPGFileName);
jpeg_destroy_decompress(&jinfo);
return;
}
jpeg_stdio_src(&jinfo, pfJPG);
//jpeg_mem_src(&jinfo,mem,insize);//decompress from mem
/*Read JPG header*/
jpeg_read_header(&jinfo, TRUE);
printf(DEBUG_INFO"Scale Num = %d\n",jinfo.scale_num);
printf(DEBUG_INFO"Scale Denom = %d\n",jinfo.scale_denom);
printf(DEBUG_INFO"Out Color Space = %d\n",jinfo.out_color_space);
//JCS_RGB = 2;
/*Start decompressing*/
jpeg_start_decompress(&jinfo);
/*Only get decompress arguments*/
//jpeg_calc_output_dimensions(&jinfo);
printf(DEBUG_INFO"Output Width = %d\n",jinfo.output_width);
printf(DEBUG_INFO"Output Height = %d\n",jinfo.output_height);
//Color Channel
printf(DEBUG_INFO"Output Components = %d\n",jinfo.output_components);
/*Alloc buffer memory for row data*/
row_stride = jinfo.output_width * jinfo.output_components;
ppucRowData = (*jinfo.mem->alloc_sarray)((j_common_ptr) &jinfo, JPOOL_IMAGE, row_stride, 1);
/*Read Data by ScanLine*/
uiRealWidth = MIN(uiLCDWidth-x,jinfo.output_width);
uiRealHeight = MIN(uiLCDHeight-y,jinfo.output_height);
while (jinfo.output_scanline < uiRealHeight) //jinfo.output_height
{
int line = 0;
jpeg_read_scanlines(&jinfo, ppucRowData, 1);
//output_scanline start from 0,but after scanline it will add 1
line=jinfo.output_scanline-1;
for(i=0;i < uiRealWidth;i++) //jinfo.output_width
{//put pixel into framebuffer
stColor.ucRed = ppucRowData[0][i*3];
stColor.ucGreen = ppucRowData[0][i*3+1];
stColor.ucBlue = ppucRowData[0][i*3+2];
DrawAPoint(hCanvas,x + i, y + line, stColor);
}
}//end while
/*Finish Decompress*/
jpeg_finish_decompress(&jinfo);
/*Destroy Decompress Object*/
jpeg_destroy_decompress(&jinfo);
fclose(pfJPG);
}
int GetFileSize(char * path)
{
FILE *fp;
int length;
fp=fopen(path,"rb");
if(fp==NULL)
printf("file not found!\n");
else
{ //把文件的位置指针移到文件尾
fseek(fp,0L,SEEK_END);
//获取文件长度;
length=ftell(fp);
printf("The length is %1d bytes\n",length);
fclose(fp);
}
return length+1;
}
void DrawJPGFromMem(HCANVAS hCanvas,
const unsigned char * pucJPGData,//第二个参数是指内存首地址
int x,int y,unsigned long ulLenOfJPGData)
{
St_Canvas *pstCanvas=hCanvas;
unsigned int uiLCDWidth=0;
unsigned int uiLCDHeight=0;
int i=0;
JSAMPARRAY ppucRowData=NULL;
St_RGB stColor={0};
struct jpeg_decompress_struct jinfo;
struct jpeg_error_mgr jerr;
unsigned int row_stride=0;
unsigned long uiRealWidth=0;
unsigned long uiRealHeight=0;
if(NULL==pstCanvas)
{
printf(DEBUG_ERROR"in file :%s:%d:Invalid Canvas!!!\n",__FILE__,__LINE__);
return;
}
if(NULL==pstCanvas->hLCDDev)
{
printf(DEBUG_ERROR"in file:%s:%d:Invalid hLCDDev!!!\n ",__FILE__,__LINE__);
return;
}
uiLCDWidth=GetLCDWidth(pstCanvas->hLCDDev);
uiLCDHeight=GetLCDHeight(pstCanvas->hLCDDev);
if(x<0||x>=uiLCDWidth||y<0||y>=uiLCDHeight)
{
printf(DEBUG_WARNING"in file:%s:%d:Invalid value of point(%d,%d)!!!\n",__FILE__,__LINE__,x,y);
return;
}
//绑定错误
jinfo.err=jpeg_std_error(&jerr);
//创建压缩对象
jpeg_create_decompress(&jinfo);
jpeg_mem_src(&jinfo,pucJPGData,ulLenOfJPGData);
jpeg_read_header(&jinfo,TRUE);
printf(DEBUG_INFO"Scale Num = %d\n",jinfo.scale_num);
printf(DEBUG_INFO"Scale Denom = %d\n",jinfo.scale_denom);
printf(DEBUG_INFO"Out Color Space = %d\n",jinfo.out_color_space);
jpeg_start_decompress(&jinfo);
printf(DEBUG_INFO"Output Width = %d\n",jinfo.output_width);
printf(DEBUG_INFO"Output Height = %d\n",jinfo.output_height);
//Color Channel
printf(DEBUG_INFO"Output Components = %d\n",jinfo.output_components);
row_stride=jinfo.output_width*jinfo.output_height;
ppucRowData=(*jinfo.mem->alloc_sarray)((j_common_ptr)&jinfo,JPOOL_IMAGE,row_stride,1);
uiRealWidth = MIN(uiLCDWidth-x,jinfo.output_width);
uiRealHeight = MIN(uiLCDHeight-y,jinfo.output_height);
while(jinfo.output_scanline<uiRealHeight)
{
int line=0;
jpeg_read_scanlines(&jinfo,ppucRowData,1);
line=jinfo.output_scanline-1;
for(i=0;i < uiRealWidth;i++) //jinfo.output_width
{//put pixel into framebuffer
stColor.ucRed = ppucRowData[0][i*3];//每个像素的颜色要用三个字节表示
stColor.ucGreen = ppucRowData[0][i*3+1];
stColor.ucBlue = ppucRowData[0][i*3+2];
DrawAPoint(hCanvas,x + i, y + line, stColor);
}
}
/*Finish Decompress*/
jpeg_finish_decompress(&jinfo);
/*Destroy Decompress Object*/
jpeg_destroy_decompress(&jinfo);
return;
}