📄 dim_jpeg_format_io.cpp
字号:
} // extern Cinline my_jpeg_destination_mgr::my_jpeg_destination_mgr(FILE* new_stream){ jpeg_destination_mgr::init_destination = dimjpeg_init_destination; jpeg_destination_mgr::empty_output_buffer = dimjpeg_empty_output_buffer; jpeg_destination_mgr::term_destination = dimjpeg_term_destination; stream = new_stream; next_output_byte = buffer; free_in_buffer = max_buf;}*/
struct my_jpeg_destination_mgr : public jpeg_destination_mgr {
// Nothing dynamic - cannot rely on destruction over longjump
TDimFormatHandle *fmtHndl;
JOCTET buffer[max_buf];
public:
my_jpeg_destination_mgr(TDimFormatHandle *new_hndl);
};
extern "C" {
static void dimjpeg_init_destination(j_compress_ptr)
{
}
static void dimjpeg_exit_on_error(j_compress_ptr cinfo, TDimFormatHandle *fmtHndl)
{
// cinfo->err->msg_code = JERR_FILE_WRITE;
dimFlush( fmtHndl );
(*cinfo->err->error_exit)((j_common_ptr)cinfo);
}
static boolean dimjpeg_empty_output_buffer(j_compress_ptr cinfo)
{
my_jpeg_destination_mgr* dest = (my_jpeg_destination_mgr*)cinfo->dest;
if ( dimWrite( dest->fmtHndl, (char*)dest->buffer, 1, max_buf) != max_buf )
dimjpeg_exit_on_error(cinfo, dest->fmtHndl);
dimFlush( dest->fmtHndl );
dest->next_output_byte = dest->buffer;
dest->free_in_buffer = max_buf;
return TRUE;
}
static void dimjpeg_term_destination(j_compress_ptr cinfo)
{
my_jpeg_destination_mgr* dest = (my_jpeg_destination_mgr*)cinfo->dest;
unsigned int n = max_buf - dest->free_in_buffer;
if ( dimWrite( dest->fmtHndl, (char*)dest->buffer, 1, n ) != n )
dimjpeg_exit_on_error(cinfo, dest->fmtHndl);
dimFlush( dest->fmtHndl );
dimjpeg_exit_on_error( cinfo, dest->fmtHndl );
}
} // extern C
inline my_jpeg_destination_mgr::my_jpeg_destination_mgr(TDimFormatHandle *new_hndl)
{
jpeg_destination_mgr::init_destination = dimjpeg_init_destination;
jpeg_destination_mgr::empty_output_buffer = dimjpeg_empty_output_buffer;
jpeg_destination_mgr::term_destination = dimjpeg_term_destination;
fmtHndl = new_hndl;
next_output_byte = buffer;
free_in_buffer = max_buf;
}
//----------------------------------------------------------------------------
// WRITE PROC
//----------------------------------------------------------------------------static int write_jpeg_image( TDimFormatHandle *fmtHndl ){ TDimImageBitmap *image = fmtHndl->image;
struct jpeg_compress_struct cinfo; JSAMPROW row_pointer[1]; row_pointer[0] = 0; //struct my_jpeg_destination_mgr *iod_dest = new my_jpeg_destination_mgr( fmtHndl->stream );
struct my_jpeg_destination_mgr *iod_dest = new my_jpeg_destination_mgr( fmtHndl ); struct my_error_mgr jerr;
cinfo.err = jpeg_std_error(&jerr); jerr.error_exit = my_error_exit; if (!setjmp(jerr.setjmp_buffer))
{ jpeg_create_compress(&cinfo); cinfo.dest = iod_dest; cinfo.image_width = image->i.width; cinfo.image_height = image->i.height;
TDimLUT* cmap=0; bool gray=TRUE;
if ( image->i.samples == 1 )
{
cinfo.input_components = 1;
cinfo.in_color_space = JCS_GRAYSCALE;
gray = TRUE;
}
else
{ cinfo.input_components = 3; cinfo.in_color_space = JCS_RGB;
gray = FALSE;
}
if ( image->i.depth < 8 )
{
cmap = &image->i.lut;
gray = TRUE;
if (cmap->count > 0) gray = FALSE;
cinfo.input_components = gray ? 1 : 3;
cinfo.in_color_space = gray ? JCS_GRAYSCALE : JCS_RGB;
}
jpeg_set_defaults(&cinfo); int quality = fmtHndl->quality;
if (quality < 1) quality = 1;
if (quality > 100) quality = 100;
jpeg_set_quality(&cinfo, quality, TRUE ); // limit to baseline-JPEG values ); jpeg_start_compress(&cinfo, TRUE);
row_pointer[0] = new uchar[cinfo.image_width*cinfo.input_components]; int w = cinfo.image_width;
long lineSizeBytes = getLineSizeInBytes( image );
while (cinfo.next_scanline < cinfo.image_height)
{ uchar *row = row_pointer[0];
/* switch ( image.depth() )
{ case 1: if (gray)
{ uchar* data = image.scanLine(cinfo.next_scanline); if ( image.bitOrder() == QImage::LittleEndian )
{ for (int i=0; i<w; i++)
{ bool bit = !!(*(data + (i >> 3)) & (1 << (i & 7))); row[i] = qRed(cmap[bit]); } }
else
{ for (int i=0; i<w; i++)
{ bool bit = !!(*(data + (i >> 3)) & (1 << (7 -(i & 7)))); row[i] = qRed(cmap[bit]); } } }
else
{ uchar* data = image.scanLine(cinfo.next_scanline); if ( image.bitOrder() == QImage::LittleEndian ) { for (int i=0; i<w; i++) { bool bit = !!(*(data + (i >> 3)) & (1 << (i & 7))); *row++ = qRed(cmap[bit]); *row++ = qGreen(cmap[bit]); *row++ = qBlue(cmap[bit]); } } else { for (int i=0; i<w; i++) { bool bit = !!(*(data + (i >> 3)) & (1 << (7 -(i & 7)))); *row++ = qRed(cmap[bit]); *row++ = qGreen(cmap[bit]); *row++ = qBlue(cmap[bit]); } } }
break;
*/
//if 4 bits per sample, there should be only one sample
if (image->i.depth == 4)
{
if (gray)
{
uchar* pix = ((uchar *) image->bits[0]) + lineSizeBytes * cinfo.next_scanline;
uchar pixH, pixL;
for (int i=0; i<lineSizeBytes; i++)
{
pixH = (unsigned char) ((*pix) << 4);
pixL = (unsigned char) ((*pix) >> 4);
*row++ = pixH;
if (i+1<w) *row++ = pixL;
pix++;
}
} // if one sample with 8 bits
else
{
uchar pixH, pixL;
uchar* pix = ((uchar *) image->bits[0]) + lineSizeBytes * cinfo.next_scanline;
for (int i=0; i<lineSizeBytes; i++)
{
pixH = (unsigned char) ((*pix) << 4);
pixL = (unsigned char) ((*pix) >> 4);
*row++ = (unsigned char) dimR( cmap->rgba[pixH] );
*row++ = (unsigned char) dimG( cmap->rgba[pixH] );
*row++ = (unsigned char) dimB( cmap->rgba[pixH] );
if (i+1<w)
{
*row++ = (unsigned char) dimR( cmap->rgba[pixL] );
*row++ = (unsigned char) dimG( cmap->rgba[pixL] );
*row++ = (unsigned char) dimB( cmap->rgba[pixL] );
}
pix++;
}
} // if paletted image
} // 4 bits per sample
//if 8 bits per sample
if (image->i.depth == 8)
{
if (gray)
{
uchar* pix = ((uchar *) image->bits[0]) + lineSizeBytes * cinfo.next_scanline;
memcpy( row, pix, w );
row += w;
} // if one sample with 8 bits
else
{
if (image->i.samples == 1)
{
uchar* pix = ((uchar *) image->bits[0]) + lineSizeBytes * cinfo.next_scanline;
for (int i=0; i<w; i++)
{
*row++ = (unsigned char) dimR( cmap->rgba[*pix] );
*row++ = (unsigned char) dimG( cmap->rgba[*pix] );
*row++ = (unsigned char) dimB( cmap->rgba[*pix] );
pix++;
}
} // if paletted image
if (image->i.samples == 2)
{
uchar* pix1 = ((uchar *) image->bits[0]) + lineSizeBytes * cinfo.next_scanline;
uchar* pix2 = ((uchar *) image->bits[1]) + lineSizeBytes * cinfo.next_scanline;
for (int i=0; i<w; i++)
{
*row++ = *pix1;
*row++ = *pix2;
*row++ = 0;
pix1++; pix2++;
}
} // if 2 samples
if (image->i.samples >= 3)
{
uchar* pix1 = ((uchar *) image->bits[0]) + lineSizeBytes * cinfo.next_scanline;
uchar* pix2 = ((uchar *) image->bits[1]) + lineSizeBytes * cinfo.next_scanline;
uchar* pix3 = ((uchar *) image->bits[2]) + lineSizeBytes * cinfo.next_scanline;
for (int i=0; i<w; i++)
{
*row++ = *pix1;
*row++ = *pix2;
*row++ = *pix3;
pix1++; pix2++; pix3++;
}
} // if 3 or more samples
} // if not gray
} // 8 bits per sample
//if 16 bits per sample
if (image->i.depth == 16)
{
if (image->i.samples == 1)
{
DIM_UINT16* pix = (DIM_UINT16*) (((uchar *) image->bits[0]) + lineSizeBytes * cinfo.next_scanline);
for (int i=0; i<w; i++)
{
*row++ = (uchar) (*pix / 256);
++pix;
}
} // if paletted image
if (image->i.samples == 2)
{
DIM_UINT16* pix1 = (DIM_UINT16*) (((uchar *) image->bits[0]) + lineSizeBytes * cinfo.next_scanline);
DIM_UINT16* pix2 = (DIM_UINT16*) (((uchar *) image->bits[1]) + lineSizeBytes * cinfo.next_scanline);
for (int i=0; i<w; i++)
{
*row++ = (uchar) (*pix1 / 256);
*row++ = (uchar) (*pix2 / 256);
*row++ = 0;
++pix1; ++pix2;
}
} // if 2 samples
if (image->i.samples >= 3)
{
DIM_UINT16* pix1 = (DIM_UINT16*) (((uchar *) image->bits[0]) + lineSizeBytes * cinfo.next_scanline);
DIM_UINT16* pix2 = (DIM_UINT16*) (((uchar *) image->bits[1]) + lineSizeBytes * cinfo.next_scanline);
DIM_UINT16* pix3 = (DIM_UINT16*) (((uchar *) image->bits[2]) + lineSizeBytes * cinfo.next_scanline);
for (int i=0; i<w; i++)
{
*row++ = (uchar) (*pix1 / 256);
*row++ = (uchar) (*pix2 / 256);
*row++ = (uchar) (*pix3 / 256);
++pix1; ++pix2; ++pix3;
}
} // if 3 or more samples
} // 16 bits per sample
jpeg_write_scanlines(&cinfo, row_pointer, 1); } jpeg_finish_compress(&cinfo); jpeg_destroy_compress(&cinfo); } delete iod_dest; delete row_pointer[0];
return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -