📄 jdmain.c
字号:
#include <stdio.h>
#include <string.h>
#include <malloc.h>
#include <stdlib.h>
#include <math.h>
#include "jddatatype.h"
#include "jdprototype.h"
#define SCREEN_WIDTH 480
#define SCREEN_HEIGHT 320
INT16 count;
void main ()
{
JPEG_DECODER_STRUCTURE g_jpeg_decoder_structure;
UINT8 *input ;
FILE *fpt;
long start, length;
int tmp;
UINT16 *RGBbuffer, *NewRGBbuffer;
UINT16 number_of_lines, number_of_samples_per_line;
UINT16 zoomwidth, zoomheight;
g_jpeg_decoder_structure.coefficient_buffer = (INT16*)jdmalloc(5000000L*sizeof(INT16)); //may be you can recude the size
if(!g_jpeg_decoder_structure.coefficient_buffer)
{
printf("Memory Allocation Failed\n");
exit(0);
}
yuv2rgb_init_lookup();
//Loop for jpeg files decoding
{
INT8 *input_filename = "test2.jpg";
INT8 *output_filename = "test2.bmp";
count = 0;
fpt = fopen (input_filename, "rb");
fseek(fpt,0,0);
start=ftell(fpt);
fseek(fpt,0,2);
length = ftell(fpt)-start;
fseek(fpt,0,0);
input = (UINT8 *)malloc(length*sizeof(UINT8));
if(!input)
{
printf("Can not allocate memory\n");
exit(0);
}
fread (input, 1, length, fpt);
fclose (fpt);
g_jpeg_decoder_structure . input_ptr = input;
tmp = jpeg_decoder (&g_jpeg_decoder_structure);
if(tmp!= 0)
{
printf("\nError %d",tmp);
free(input);
free(g_jpeg_decoder_structure . const_image_buffer);
exit(0);
}
number_of_lines = g_jpeg_decoder_structure.number_of_lines;
number_of_samples_per_line = g_jpeg_decoder_structure.number_of_samples_per_line&0xfffe;
RGBbuffer = (UINT16 *)malloc(number_of_lines*number_of_samples_per_line*sizeof(UINT16));
write_rgb565buffer(g_jpeg_decoder_structure.const_image_buffer, number_of_lines,
number_of_samples_per_line, RGBbuffer);
NewRGBbuffer = NULL;
if((number_of_samples_per_line > SCREEN_WIDTH)||(number_of_lines > SCREEN_HEIGHT))
{
float ZoomRatioX,ZoomRatioY,ZoomRatio;
ZoomRatioX = (float)SCREEN_WIDTH/number_of_samples_per_line;
ZoomRatioY = (float)SCREEN_HEIGHT/number_of_lines;
if(ZoomRatioX <= ZoomRatioY)
ZoomRatio = ZoomRatioX;
else
ZoomRatio = ZoomRatioY;
zoomwidth = ((UINT16)(ZoomRatio*number_of_samples_per_line+0.5))&0xfffc;
ZoomRatio = (float)zoomwidth/number_of_samples_per_line;
zoomheight = (UINT16)(ZoomRatio*number_of_lines+0.5);
NewRGBbuffer = (UINT16 *)malloc(zoomwidth*zoomheight*sizeof(UINT16));
InterpolaZoom(RGBbuffer, number_of_samples_per_line, number_of_lines, ZoomRatio, NewRGBbuffer);
}
fpt = fopen (output_filename, "wb");
if(!NewRGBbuffer)
write_bmp (RGBbuffer,number_of_lines,number_of_samples_per_line,fpt);
else
{
write_bmp (NewRGBbuffer,zoomheight,zoomwidth,fpt);
free(NewRGBbuffer);
}
fclose (fpt);
free(input);
free(g_jpeg_decoder_structure . const_image_buffer);
free(RGBbuffer);
}
//end of loop
free(g_jpeg_decoder_structure.coefficient_buffer);
}
void write_bmp (UINT16 * RGBbuf, UINT16 number_of_lines,
UINT16 number_of_samples_per_line, FILE * fw)
{
UINT16 i, j, size, tmp, *img;
size = 54 + number_of_samples_per_line * number_of_lines;
fputc (0x42, fw);
fputc (0x4d, fw);
fputc (size & 0xff, fw);
fputc (size >> 8 & 0xff, fw);
fputc (size >> 16 & 0xff, fw);
fputc (size >> 24 & 0xff, fw);
fputc (0, fw);
fputc (0, fw);
fputc (0, fw);
fputc (0, fw);
fputc (54, fw);
fputc (0, fw);
fputc (0, fw);
fputc (0, fw);
fputc (40, fw);
fputc (0, fw);
fputc (0, fw);
fputc (0, fw);
fputc ((UINT16) number_of_samples_per_line & 0xff, fw);
fputc ((UINT16) (number_of_samples_per_line >> 8) & 0xff, fw);
fputc (0, fw);
fputc (0, fw);
fputc ((UINT16) number_of_lines & 0xff, fw);
fputc ((UINT16) (number_of_lines >> 8) & 0xff, fw);
fputc (0, fw);
fputc (0, fw);
fputc (1, fw);
fputc (0, fw);
// fputc (24, fw);
fputc (16, fw); //16 bits RGB
fputc (0, fw);
fputc (0, fw);
fputc (0, fw);
fputc (0, fw);
fputc (0, fw);
fputc (0, fw);
fputc (0, fw);
fputc (0, fw);
fputc (0, fw);
fputc (0, fw);
fputc (0, fw);
fputc (0, fw);
fputc (0, fw);
fputc (0, fw);
fputc (0, fw);
fputc (0, fw);
fputc (0, fw);
fputc (0, fw);
fputc (0, fw);
fputc (0, fw);
fputc (0, fw);
fputc (0, fw);
fputc (0, fw);
fputc (0, fw);
fputc (0, fw);
img = RGBbuf;
for (i=0 ; i<number_of_lines; i++)
{
for (j=0; j<number_of_samples_per_line/* >> 1*/; j++)
{
fwrite(img, 2, 1, fw);
img++;
}
tmp = 4 - ((number_of_samples_per_line * 3) & 3);
if (tmp != 4)
{
for (j=0; j<tmp; j++)
fputc (0, fw);
}
}
}
void* jdmalloc(size_t size)
{
return(malloc(size));
}
void YUV_to_RGB24(const UINT8 Y, const UINT8 U, const UINT8 V, UINT8 *R, UINT8 *G, UINT8 *B)
{
*R = CLIP( (g_298[Y] + g_409[V] + 128) >> 8);
*G = CLIP( (g_298[Y] - g_100[U] - g_208[V] + 129) >> 8);
*B = CLIP( (g_298[Y] + g_516[U] + 128) >> 8);
}
void YUV_to_RGB565(const UINT8 Y, const UINT8 U, const UINT8 V, UINT16 *pRGBPixel)
{
UINT16 R, G, B;
R = CLIP( (g_298[Y] + g_409[V] + 128) >> 8);
G = CLIP( (g_298[Y] - g_100[U] - g_208[V] + 129) >> 8);
B = CLIP( (g_298[Y] + g_516[U] + 128) >> 8);
// *pRGBPixel = (((R&0x00f8)<<8)|((G&0x00fc)<<3)|((B&0x00f8)>>3)); //RGB565
*pRGBPixel = (((R&0x00f8)<<7)|((G&0x00f8)<<2)|((B&0x00f8)>>3)); //RGB555
}
void yuv2rgb_init_lookup()
{
int i;
for(i=0; i<256; i++)
{
g_298[i] = 298 * (i-16);
g_409[i] = 409 * (i-128);
g_100[i] = 100 * (i-128);
g_208[i] = 208 * (i-128);
g_516[i] = 516 * (i-128);
}
}
void write_rgb565buffer (UINT32 * image, UINT16 number_of_lines,
UINT16 number_of_samples_per_line, UINT16 *RGBbuf)
{
UINT16 i, j, *img;
UINT8 Y1, Y2, CB, CR;
UINT16 *RGBPixel = RGBbuf;
img = (UINT16 *) (image + (number_of_lines - 1) * (number_of_samples_per_line >> 1));
for (i=0 ; i<number_of_lines; i++)
{
for (j=0; j<number_of_samples_per_line >> 1; j++)
{
Y1 = *img >> 8;
CB = *img++ & 0xff;
Y2 = *img >> 8;
CR = *img++ & 0xff;
YUV_to_RGB565(Y1, CB, CR, RGBPixel);
RGBPixel++;
YUV_to_RGB565(Y2, CB, CR, RGBPixel);
RGBPixel++;
}
img -= number_of_samples_per_line << 1;
}
}
void InterpolaZoom(UINT16 *lpDIBBits, UINT16 lWidth, UINT16 lHeight, float ZoomRatio, UINT16 * lpNewDIBBits)
{
// 缩放后图像的宽度和高度
UINT16 lNewWidth;
UINT16 lNewHeight;
/***************************/
/** 编写: 计算放大后新的图像高度和宽度 **/
// 指向缩放图像对应象素的指针
UINT16 *lpDst;
// 循环变量(象素在新DIB中的坐标)
INT32 i;
INT32 j;
// 象素在源DIB中的坐标
INT32 i0;
INT32 j0;
// 图像每行的字节数
// UINT16 lLineBytes;
// 四个最临近象素的坐标(i1, j1), (i2, j1), (i1, j2), (i2, j2)
INT32 i1, i2;
INT32 j1, j2;
// 四个最临近象素值
// unsigned char f1, f2, f3, f4;
UINT16 f1, f2, f3, f4;
// 二个插值中间值
// unsigned char f12, f34;
UINT16 f12, f34;
// 定义一个值,当象素坐标相差小于改值时认为坐标相同
float EXP;
// 计算缩放后的图像实际宽度
lNewWidth = (UINT16) (lWidth * ZoomRatio + 0.5);
// 计算缩放后的图像高度
lNewHeight = (UINT16) (lHeight * ZoomRatio + 0.5);
/****************************/
/*编写:通过双线性插值计算出的每个象素的值
并要判断是否落在原图中,若没有灰度值置0或255*/
// 赋值
EXP = 0.0001;
// 针对图像每行进行操作
for(i = 0; i < lNewHeight; i++)
{
// 针对图像每列进行操作
for(j = 0; j < lNewWidth; j++)
{
// 指向新DIB第i行,第j个象素的指针
// 注意此处宽度和高度是新DIB的宽度和高度
lpDst = lpNewDIBBits + lNewWidth * (lNewHeight - 1 - i) + j;
// 计算该象素在源DIB中的坐标
i0 = (INT32) (i / ZoomRatio + 0.5);
j0 = (INT32) (j / ZoomRatio + 0.5);
// 计算四个最临近象素的坐标
i1 = i0;
i2 = i1 + 1;
j1 = j0;
j2 = j1 + 1;
// 根据不同情况分别处理
if( (j0 < 0) || (j0 > lWidth - 1) || (i0 < 0) || (i0 > lHeight - 1))
{
// 要计算的点不在源图范围内,直接返回255。
*lpDst=(UINT16)0x7fff;
}
else
{
if (fabs(j0 - lWidth + 1) <= EXP)
{
// 要计算的点在图像右边缘上
if (fabs(i0 - lHeight + 1) <= EXP)
{
// 要计算的点正好是图像最右下角那一个象素,直接返回该点象素值
f1 = *(lpDIBBits + lWidth * (lHeight - 1 - i1) + j1);
*lpDst=(UINT16) f1;
}
else
{
// 在图像右边缘上且不是最后一点,直接一次插值即可
f1 = *(lpDIBBits + lWidth * (lHeight - 1 - i1) + j1);
f3 = *(lpDIBBits + lWidth * (lHeight - 1 - i2) + j2);
// 返回插值结果
*lpDst=(UINT16)( f1 + (i0 -i1) * (f3 - f1));
}
}
else if (fabs(i0 - lHeight + 1) <= EXP)
{
// 要计算的点在图像下边缘上且不是最后一点,直接一次插值即可
f1 = *(lpDIBBits + lWidth * (lHeight - 1 - i1) + j1);
f2 = *(lpDIBBits + lWidth * (lHeight - 1 - i1) + j2);
// 返回插值结果
*lpDst=(UINT16) (f1 + (j0 -j1) * (f2 - f1));
}
else
{
// 计算四个最临近象素值
f1 = *(lpDIBBits + lWidth * (lHeight - 1 - i1) + j1);
f2 = *(lpDIBBits + lWidth * (lHeight - 1 - i1) + j2);
f3 = *(lpDIBBits + lWidth * (lHeight - 1 - i2) + j1);
f4 = *(lpDIBBits + lWidth * (lHeight - 1 - i2) + j2);
// 插值1
f12 = (UINT16) (f1 + (j0 - j1) * (f2 - f1));
// 插值2
f34 = (UINT16) (f3 + (j0 - j1) * (f4 - f3));
// 插值3
*lpDst=(UINT16) (f12 + (i0 -i1) * (f34 - f12));
}
}
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -