|
楼主 |
发表于 2008-3-26 21:20:25
|
显示全部楼层
没想到今天才来就召唤到大神鸟~
谢谢白银的回答。我看War3ModelEditor的代码,是用IJG的库做jpeg解码的,我也是跟着来。只是那个JPEG公用的文件头,如何找到大小的数据呢?我一直没有查到相关资料。现在倒好,找了个取巧的办法,但是也行的通了。
[code=cpp]
// 读取JPEG文件头
GLint jpeg_header_size;
is.read(jpeg_header_size);
std::vector<GLubyte> jpeg_header(jpeg_header_size);
is.checkedRead(&jpeg_header[0], jpeg_header_size);
// 读取mipmap
std::vector<GLubyte> mipmap_pixels[BLP_MAX_MIPMAP];
int levels = 0;
for(int i=0; i<BLP_MAX_MIPMAP; ++i) {
if( header.MipmapSize <= 0 )
break;
++levels;
is.seekFromStart(header.MipmapOffset);
mipmap_pixels = std::vector<GLubyte>(header.MipmapSize);
is.checkedRead(&mipmap_pixels[0], header.MipmapSize);
}
// JPEG解压缩
jpeg_decompress_struct cinfo;
jpeg_error_mgr jerr;
cinfo.err = jpeg_std_error(&jerr);
jpeg_create_decompress(&cinfo);
GLint width = header.Width;
GLint height = header.Height;
// 本该循环解压各mipmap,但是这里仅解第一层
for(int i=0; i<levels; ++i, width=max(width/2, 1), height=max(height/2, 1)) {
// for(int i=0; i<1; ++i, width=max(width/2, 1), height=max(height/2, 1)) {
// 构造一个JPEG数据
MemoryInputStreamAdapter
is_header(&jpeg_header[0], jpeg_header_size),
is_pixels(&mipmap_pixels[0], header.MipmapSize);
InputStream* stream_list[] = {&is_header, &is_pixels};
ConcatInputStreamAdapter is_concat(
std::vector<InputStream*>(stream_list, stream_list+2));
JpegSourceMgr sm(is_concat);
cinfo.src = &sm;
// 读取JPEG头(注意每次重新设置高度和宽度)
jpeg_read_header(&cinfo, TRUE);
cinfo.output_width = width;
cinfo.output_height = height;
// 解压缩
jpeg_start_decompress(&cinfo);
const GLint components = cinfo.output_components;
const int line_bytes = (width * components+3)/4*4; // 每行像素使用的字节数,四字节对齐
std::vector<unsigned char> pixels(line_bytes * height);
for(int j=0; j<height; ++j) { // 逐行解压缩,注意垂直方向反转
unsigned char* read_out_ptr = &pixels[(height-j-1)*line_bytes];
JSAMPROW pixel_rows[] = {(JSAMPROW)read_out_ptr};
jpeg_read_scanlines(&cinfo, pixel_rows, 1);
}
jpeg_finish_decompress(&cinfo);
// 用解压后的数据覆盖原来的数据
mipmap_pixels = pixels;
}
jpeg_destroy_decompress(&cinfo);
[/code] |
|