解説
Independent JPEG Groupが提供しているJPEGライブラリを使用したJPEGファイルの読み込み。
ライブラリ作成時はライブラリのソースファイルには一切変更を加えずにライブラリをビルドしlibjpeg.libを得る。
※ ヘッダーファイルに変更を加えれば「extern "C"」や「XMD_H」の定義、RGBの並び順変更などをライブラリ利用時に行なう必要がなくなる
読み込んだ画像はCBitmap形式でCJpeg::m_lpcBitmapに保存される。
グレースケールJPEGファイルなどには未対応。
使用例
//jpgファイルの読込
void test(void)
{
CJpeg cJpeg;
cJpeg.SimpleOpen("Dscf1998.jpg");
}
extern "C"
{
#define XMD_H // INT32の再定義エラー防止
#include "Jpeglib.h"
#include "jerror.h"
}
#pragma comment(lib,"libjpeg.lib")
#include "afxtempl.h"
class CJpeg
{
public:
CJpeg();
virtual ~CJpeg();
CBitmap* m_lpcBitmap;
static void _JpegError(j_common_ptr cinfo);
bool SimpleOpen(CString strFile);
};
CJpeg::CJpeg()
{
m_lpcBitmap = new CBitmap;
}
CJpeg::~CJpeg()
{
if(m_lpcBitmap != NULL)
delete m_lpcBitmap;
}
//
// エラーハンドラ
//
void CJpeg::_JpegError(j_common_ptr cinfo)
{
AfxThrowUserException();
}
//
// Jpegファイルの読込
//
// ※ マーカー情報の読込処理は未インプリメント
//
bool CJpeg::SimpleOpen(CString strFile)
{
m_lpcBitmap->DeleteObject();
int i;
int nJpegLineBytes; //JPEG1ラインのバイト数
long nBmpLineBytes; //Bitmap1ラインのバイト数
BYTE* lpbtBits;
JSAMPLE* pSample;
FILE* fp;
BITMAPINFOHEADER bmih;
HBITMAP hBmp;
JSAMPROW buffer[1];
JSAMPLE tmp;
jpeg_decompress_struct cInfo;
jpeg_error_mgr jError;
fp = NULL;
pSample = NULL;
TRY
{
fp = fopen(strFile,"rb");
if(fp == NULL)
return false;
cInfo.err = jpeg_std_error(&jError); //エラーハンドラ設定
jError.error_exit = _JpegError; //エラーハンドラ設定
jpeg_create_decompress(&cInfo); //
jpeg_stdio_src(&cInfo,fp); //読込ファイル設定
jpeg_read_header(&cInfo,TRUE); //ヘッダー読込
jpeg_start_decompress(&cInfo); //デコードスタート
//DIBSECTION作成
bmih.biSize = sizeof(bmih);
bmih.biWidth = cInfo.output_width;
bmih.biHeight = cInfo.output_height;
bmih.biPlanes = 1;
bmih.biBitCount = 24;
bmih.biCompression = BI_RGB;
bmih.biSizeImage = 0;
bmih.biXPelsPerMeter= 0;
bmih.biYPelsPerMeter= 0;
bmih.biClrUsed = 0;
bmih.biClrImportant = 0;
hBmp = ::CreateDIBSection(0,(BITMAPINFO*)&bmih,DIB_RGB_COLORS,(VOID**)&lpbtBits,0,0);
if(hBmp == NULL)
{
jpeg_destroy_decompress(&cInfo);
return false;
}
nJpegLineBytes = cInfo.output_width * cInfo.output_components; //JPEG 1ラインのバイト数
nBmpLineBytes = (cInfo.output_width * 3 + 3) & 0xfffffffcL; //Bitmap 1ラインのバイト数
pSample = new JSAMPLE[nJpegLineBytes + 10]; // ラインバッファ確保
buffer[0] = pSample;
lpbtBits += cInfo.output_height * nBmpLineBytes; //Bitmapの最下ラインにポインタ設定
while(cInfo.output_scanline < cInfo.output_height)
{
jpeg_read_scanlines(&cInfo,buffer,1); //Jpegを1ライン読み込む
for(i = 0; i < nJpegLineBytes; i += 3) //JPEGはBGRの順なのでRBG順に変換
{
tmp = buffer[0][i+0];
buffer[0][i+0] = buffer[0][i+2];
buffer[0][i+2] = tmp;
}
lpbtBits -= nBmpLineBytes; //ポインタを1ライン分ずらす
memcpy(lpbtBits,buffer[0],nBmpLineBytes); //Jpegは上から下へラインが格納、Bitmapはライン順が逆
}
delete pSample;
jpeg_finish_decompress(&cInfo); // 読み込み終了処理
jpeg_destroy_decompress(&cInfo);
fclose(fp);
m_lpcBitmap->Attach(hBmp); //結果のアタッチ
return true;
}
CATCH_ALL(e)
{
if(pSample != NULL)
delete pSample;
if(fp != NULL)
fclose(fp);
return false;
}
END_CATCH_ALL
}







