// depress_form_mem.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <iostream>
#include <stdio.h>
#include "cv.h"
#include "opencv2/opencv.hpp"
extern "C"{
#include "jpeglib.h"
};
#pragma comment(lib,"libjpeg.lib")
using namespace std;
using namespace cv;
#pragma pack(2) //两字节对齐,否则bmp_fileheader会占16Byte
struct bmp_fileheader
{
unsigned short bfType; //若不对齐,这个会占4Byte
unsigned long bfSize;
unsigned short bfReverved1;
unsigned short bfReverved2;
unsigned long bfOffBits;
};
struct bmp_infoheader
{
unsigned long biSize;
unsigned long biWidth;
unsigned long biHeight;
unsigned short biPlanes;
unsigned short biBitCount;
unsigned long biCompression;
unsigned long biSizeImage;
unsigned long biXPelsPerMeter;
unsigned long biYpelsPerMeter;
unsigned long biClrUsed;
unsigned long biClrImportant;
};
FILE *input_file;
FILE *output_file;
void write_bmp_header(j_decompress_ptr cinfo)
{
struct bmp_fileheader bfh;
struct bmp_infoheader bih;
unsigned long width;
unsigned long height;
unsigned short depth;
unsigned long headersize;
unsigned long filesize;
width=cinfo->output_width;
height=cinfo->output_height;
depth=cinfo->output_components;
if (depth==1)
{
headersize=14+40+256*4;
filesize=headersize+width*height;
}
if (depth==3)
{
headersize=14+40;
filesize=headersize+width*height*depth;
}
memset(&bfh,0,sizeof(struct bmp_fileheader));
memset(&bih,0,sizeof(struct bmp_infoheader));
//写入比较关键的几个bmp头参数
bfh.bfType=0x4D42;
bfh.bfSize=filesize;
bfh.bfOffBits=headersize;
bih.biSize=40;
bih.biWidth=width;
bih.biHeight=height;
bih.biPlanes=1;
bih.biBitCount=(unsigned short)depth*8;
bih.biSizeImage=width*height*depth;
fwrite(&bfh,sizeof(struct bmp_fileheader),1,output_file);
fwrite(&bih,sizeof(struct bmp_infoheader),1,output_file);
if (depth==1) //灰度图像要添加调色板
{
unsigned char *platte;
platte=new unsigned char[256*4];
unsigned char j=0;
for (int i=0;i<1024;i+=4)
{
platte[i]=j;
platte[i+1]=j;
platte[i+2]=j;
platte[i+3]=0;
j++;
}
fwrite(platte,sizeof(unsigned char)*1024,1,output_file);
delete[] platte;
}
}
void write_bmp_data(j_decompress_ptr cinfo,unsigned char *src_buff)
{
unsigned char *dst_width_buff;
unsigned char *point;
unsigned long width;
unsigned long height;
unsigned short depth;
width=cinfo->output_width;
height=cinfo->output_height;
depth=cinfo->output_components;
dst_width_buff=new unsigned char[width*depth];
memset(dst_width_buff,0,sizeof(unsigned char)*width*depth);
point=src_buff+width*depth*(height-1); //倒着写数据,bmp格式是倒的,jpg是正的
for (unsigned long i=0;i<height;i++)
{
for (unsigned long j=0;j<width*depth;j+=depth)
{
if (depth==1) //处理灰度图
{
dst_width_buff[j]=point[j];
}
if (depth==3) //处理彩色图
{
dst_width_buff[j+2]=point[j+0];
dst_width_buff[j+1]=point[j+1];
dst_width_buff[j+0]=point[j+2];
}
}
point-=width*depth;
fwrite(dst_width_buff,sizeof(unsigned char)*width*depth,1,output_file); //一次写一行
}
}
void mem_init_source(j_decompress_ptr cinfo)
{
// cinfo->src->bytes_in_buffer = g_buf_len;
// cinfo->src->next_input_byte = (unsigned char*)g_buf;
}
boolean mem_fill_input_buffer(j_decompress_ptr cinfo)
{
return true;
}
void mem_skip_input_data(j_decompress_ptr cinfo, long num_bytes)
{
cinfo->src->bytes_in_buffer -= num_bytes;
cinfo->src->next_input_byte += num_bytes;
}
boolean mem_resync_to_restart(j_decompress_ptr cinfo, int desired)
{
return jpeg_resync_to_restart(cinfo, desired);
}
void mem_term_source(j_decompress_ptr cinfo)
{
}
void analyse_jpeg(char *data, int size, IplImage ** img)
{
struct jpeg_decompress_struct cinfo;
struct jpeg_error_mgr jerr;
JSAMPARRAY buffer;
unsigned char *src_buff;
unsigned char *point;
/*
cinfo.err=jpeg_std_error(&jerr);
jpeg_create_decompress(&cinfo);
//jpeg_stdio_src(&cinfo,input_file);
jpeg_mem_src(&cinfo, (unsigned char *)data, size);
jpeg_read_header(&cinfo,TRUE);
jpeg_start_decompress(&cinfo);
*/
jpeg_source_mgr jmgr;
cinfo.err = jpeg_std_error(&jerr);
jpeg_create_decompress(&cinfo);
jmgr.init_source = mem_init_source;
jmgr.fill_input_buffer = mem_fill_input_buffer;
jmgr.skip_input_data = mem_skip_input_data;
jmgr.resync_to_restart = mem_resync_to_restart;
jmgr.term_source = mem_term_source;
jmgr.next_input_byte = (unsigned char*)data;
jmgr.bytes_in_buffer = size;
cinfo.src = &jmgr;
int ret = jpeg_read_header(&cinfo, TRUE);
jpeg_start_decompress(&cinfo);
int nRowSize = cinfo.output_width * cinfo.output_components;
int w =cinfo.output_width;
int h =cinfo.output_height;
char *bmpBuffer=new char[h*w*3];
JSAMPARRAY pBuffer = (*cinfo.mem->alloc_sarray)
((j_common_ptr) &cinfo, 1, nRowSize, 1);
while(cinfo.output_scanline < cinfo.output_height)
{
jpeg_read_scanlines(&cinfo, pBuffer, 1);
int start=nRowSize*(cinfo.output_scanline-1);
for(int i=0;i<nRowSize;i++)
{
bmpBuffer[start+i]=pBuffer[0][i];
}
}
printf("image width and height:%d,%d\n", cinfo.output_width, cinfo.output_height);
unsigned long width=cinfo.output_width;
unsigned long height=cinfo.output_height;
unsigned short depth=cinfo.output_components;
src_buff=new unsigned char[width*height*depth];
memset(src_buff,0,sizeof(unsigned char)*width*height*depth);
/*
buffer=(*cinfo.mem->alloc_sarray)
((j_common_ptr)&cinfo,JPOOL_IMAGE,width*depth,1);
point=src_buff;
while (cinfo.output_scanline < cinfo.output_height)
{
jpeg_read_scanlines(&cinfo,buffer,1); //读取一行jpg图像数据到buffer
memcpy(point,*buffer,width*depth); //将buffer中的数据逐行给src_buff
point+=width*depth; //一次改变一行
}
*/
//write_bmp_header(&cinfo); //写bmp文件头
//write_bmp_data(&cinfo, (unsigned char *)bmpBuffer); //写bmp像素数据
IplImage *_pImg = cvCreateImage(cvSize(w,h), 8, 3);
printf("wid:%d, widstep:%d\n",_pImg->width, _pImg->widthStep);
for (h=0; h<_pImg->height; h++)
{
for (w = 0; w < (_pImg->width * 3); w++)
{
*(_pImg->imageData+h*_pImg->widthStep+w+0)=*(bmpBuffer+3 * h * _pImg->width+w);
//*(_pImg->imageData+h*_pImg->widthStep+w+1)=*(bmpBuffer+3 * h * _pImg->width+w);
//*(_pImg->imageData+h*_pImg->widthStep+w+2)=*(bmpBuffer+3 * h * _pImg->width+w);
}
}
cvCvtColor(_pImg, _pImg, CV_RGB2BGR);
*img = cvCloneImage(_pImg);
cvReleaseImage(&_pImg);
jpeg_finish_decompress(&cinfo);
jpeg_destroy_decompress(&cinfo);
delete[] src_buff;
}
int main()
{
const char *input_file="d.jpg";
//output_file=fopen("lena.bmp","wb");
char buffer[256*1024] = {0};
//char buffer[256];
IplImage *timg = cvLoadImage("a.jpg", 1);
cvShowImage("c", timg);
cvWaitKey();
Mat mat = Mat::zeros(timg->height, timg->width, CV_8UC3);
CvMat cmat;
//cvConvert(timg, &cmat);
//cvConvertImage(timg, &mat, CV_CVTIMG_FLIP);
Mat test = cvarrToMat(timg, 0, 1, 0);
imshow("mat", test);
waitKey();
return 0;
FILE * file = fopen(input_file, "rb");
int len = fread(buffer, sizeof(char), 256 * 1024, file);
fclose(file);
IplImage *img = NULL;
char data[128*1024] = {0};
data[0] = buffer[0];
data[1] = buffer[1];
char *tmp = buffer + 2;
int length = 0;
while ((unsigned char)*tmp == 0xFF && (unsigned char)*(tmp + 1) >= 0xE0 && (unsigned char)*(tmp + 1) <= 0xEF)
{
tmp += 2;
length = ((unsigned char)*tmp << 8) + (unsigned char)*(tmp + 1);
tmp += (length + 2);
len -= (length + 4);
}
tmp -= 2;
int i = 0;
for (i = 0; i < len; i++)
{
data[i + 2] = *tmp++;
}
analyse_jpeg(data, i + 2, &img);
cvShowImage("pimg", img);
cvWaitKey();
//fclose(output_file);