苏泊尔耗的JPEG解码器[一]

来源:互联网 发布:node sass使用 编辑:程序博客网 时间:2024/06/07 20:04

长夜漫漫,偶才整出这玩意儿-___-b想想大学时BBS上有个牛人花了一个月弄出MPEG来, 偶连做个jpeg都花了这么长时间。聊以自慰的是还算是啃得比较透了。

原定的要求是:

1.要纯C,不带汇编和C++,便于移植;(话说回来,真要让偶用汇编优化也不是那么容易的事)

2.要支持渐近模式;(云风兄的文档上没有介绍渐近模式,但偶发现实际应用中还是挺多的,比如偶D盘上某个隐藏目录下面就有N多这样的图-___-|||)

3.不使用浮点运算;(想象ing:在51单片机上,在小X王986的6502芯片上,在电饭煲的面板上…无处不显露着superarhow's jpeg的LOGO~~~~~ 流口水ing....)

4.要方便。目前的使用起来就一句话:HBITMAP jpeg_load_from_file(LPCTSTR filename)就OK。当然,自己处理的API还是有的。

目前还没有实现的功能,或者说是遗憾有:

1.不支持DNL动态大小(虽然在代码里面有留,但是没有实际的图实在是难测试)

2.不支持CMYK格式(这种格式少,但也不是没有,以前有做美术的兄弟就发给过偶这种图,记得好像是用PS存的,可现在要找个PS好难)

3.不支持数学编码(估计永远都8会支持了-___-b)

工程不算大,就分篇贴出来了。有兴趣的参考。

windows下的主控单元

jpegwin32.h

***************************************** 华丽滴分隔线(之1) ***************************************

/**************************************************************************************************

  superarhow's JPEG decoder

  by superarhow(superarhow@hotmail.com).  All rights reserved.

 **************************************************************************************************/

#pragma once

#include "windows.h"

#ifdef __cplusplus
extern "C" HBITMAP jpeg_load_from_file(LPCTSTR lpszFileName);
#else
HBITMAP jpeg_load_from_file(LPCTSTR lpszFileName);
#endif

***************************************** 华丽滴分隔线(之2) ***************************************

jpegwin32.c

***************************************** 华丽滴分隔线(之3) ***************************************

#include "jpegwin32.h"
#include "jpegdec2.h"
#include "windows.h"
#include "stdio.h"

HBITMAP jpeg_load_from_file(LPCTSTR lpszFileName)
{
 jpeg_dec_rec rec;
 FILE *fp;
 DWORD len;
 BYTE *buf;
 int ret;
 BITMAPINFO info;
 HBITMAP hbmp;

 fp = fopen(lpszFileName, "rb");
 fseek(fp, 0, SEEK_END);
 len = ftell(fp);
 fseek(fp, 0, SEEK_SET);
 buf = (BYTE *)malloc(len + 2);
 fread(buf, 1, len, fp);
 /* 加上EOI标记以增加容错性 */
 buf[len] = 0xFF;
 buf[len + 1] = 0xD9;

 jpeg_init_decoder(&rec);
 rec.p_data = buf;
 rec.p_data_limit = buf + len;
 for ( ;; ) {
  ret = jpeg_decode_next_block(&rec);
  if (rec.p_data >= rec.p_data_limit) break; 
 }
 jpeg_clear_up(&rec);

 free(buf);

 if (rec.p_bgr_buffer) {
  memset(&info, 0, sizeof(BITMAPINFO));
  info.bmiHeader.biBitCount = 24;
  info.bmiHeader.biCompression = BI_RGB;
  info.bmiHeader.biHeight = -(int)rec.n_height;
  info.bmiHeader.biPlanes = 1;
  info.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
  info.bmiHeader.biWidth = rec.n_width;
  hbmp = CreateDIBSection( NULL, &info, DIB_RGB_COLORS, (void **)&buf, NULL, 0 );
  memcpy(buf, rec.p_bgr_buffer, rec.n_bytes_per_line * rec.n_height);
  return hbmp;
 }

 return NULL;
}

***************************************** 华丽滴分隔线(之4) ***************************************