libjpegとlibtiffを使ってJpegファイルをTIFFファイルに変換する

サンプルコード。試した環境は MacOSX10.5 & Xcode3.0。エラー処理等には対処していない。

#include <iostream>
#include <tiffio.h>

extern "C" {
#include <jpeglib.h>
}

using namespace std;

int main (int argc, char * const argv[])
{
    ////// Jpegを読み出す
    struct jpeg_decompress_struct cinfo;
    struct jpeg_error_mgr jerr;
    cinfo.err = jpeg_std_error( &jerr );
    jpeg_create_decompress( &cinfo );

    const string jpg_file( argv[1] );
    FILE* infile = fopen( jpg_file.c_str(), "rb" );
    if (infile == NULL) {
        exit(1);
    }

    jpeg_stdio_src( &cinfo, infile );
    jpeg_read_header( &cinfo, TRUE );
    jpeg_start_decompress( &cinfo );
    
    size_t line_buf_size = sizeof(JSAMPLE) *
                           cinfo.output_width * cinfo.out_color_components;

    unsigned char* img_buf = new unsigned char[line_buf_size*cinfo.output_height];

    JSAMPARRAY img_line_array = new JSAMPROW[cinfo.output_height];
    for (JDIMENSION i = 0; i < cinfo.output_height; i++) {
        img_line_array[i] = img_buf + (i * line_buf_size);
    }

    while (cinfo.output_scanline < cinfo.output_height) {
        jpeg_read_scanlines( &cinfo,
                             img_line_array+cinfo.output_scanline,
                             cinfo.output_height - cinfo.output_scanline );
    }

    ////// TIFFに書き出す
    const string tif_file( jpg_file+".tif" );
    TIFF *tif_img = TIFFOpen( tif_file.c_str(), "w" );
    if (tif_img == NULL) {
        exit(1);
    }

    double xres = 72.0, yres = 72.0;
    if (cinfo.density_unit == 1) {
        xres = cinfo.X_density;
        yres = cinfo.Y_density;
    }
    else if (cinfo.density_unit == 2) {
        xres = cinfo.X_density * 2.54;
        yres = cinfo.Y_density * 2.54;
    }
    if (xres <= 1.0 || yres <= 1.0 || xres > 3000.0 || yres > 3000.0) {
        xres = 72.0;
        yres = 72.0;
    }

    TIFFSetField( tif_img, TIFFTAG_IMAGEWIDTH,      cinfo.output_width );
    TIFFSetField( tif_img, TIFFTAG_IMAGELENGTH,     cinfo.output_height );
    TIFFSetField( tif_img, TIFFTAG_BITSPERSAMPLE,   8 );
    TIFFSetField( tif_img, TIFFTAG_SAMPLESPERPIXEL, cinfo.out_color_components );
    TIFFSetField( tif_img, TIFFTAG_ROWSPERSTRIP,    cinfo.output_height );
    TIFFSetField( tif_img, TIFFTAG_COMPRESSION,     COMPRESSION_LZW );
    TIFFSetField( tif_img, TIFFTAG_PHOTOMETRIC,     PHOTOMETRIC_RGB );
    TIFFSetField( tif_img, TIFFTAG_PLANARCONFIG,    PLANARCONFIG_CONTIG );
    TIFFSetField( tif_img, TIFFTAG_XRESOLUTION,     xres );
    TIFFSetField( tif_img, TIFFTAG_YRESOLUTION,     yres );
    TIFFSetField( tif_img, TIFFTAG_RESOLUTIONUNIT,  RESUNIT_INCH );

    TIFFWriteEncodedStrip( tif_img, 0, img_buf, line_buf_size*cinfo.output_height );

    ////// 後片付けする
    TIFFClose( tif_img );

    jpeg_finish_decompress( &cinfo );
    jpeg_destroy_decompress( &cinfo );

    delete[] img_buf;
    delete[] img_line_array;

    return 0;
}