⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dim_jpeg_format_io.cpp

📁 Digital Notebook Source Code v1.1.0 [
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/*****************************************************************************
  JPEG IO 
  Copyright (c) 2004 by Dmitry V. Fedorov <www.dimin.net> <dima@dimin.net>

  IMPLEMENTATION
  
  Programmer: Dima V. Fedorov <mailto:dima@dimin.net> <http://www.dimin.net/>
    

  History:
    03/29/2004 22:23 - First creation
    08/04/2004 22:25 - Update to FMT_IFS 1.2, support for io protorypes
        
  Ver : 2
*****************************************************************************/
#include "dim_jpeg_format.h"

struct my_error_mgr : public jpeg_error_mgr {    jmp_buf setjmp_buffer;};
extern "C" {static void my_error_exit (j_common_ptr cinfo){    my_error_mgr* myerr = (my_error_mgr*) cinfo->err;    char buffer[JMSG_LENGTH_MAX];    (*cinfo->err->format_message)(cinfo, buffer);    longjmp(myerr->setjmp_buffer, 1);}}static const int max_buf = 4096;

//****************************************************************************
// READ STUFF
//****************************************************************************/*struct my_jpeg_source_mgr : public jpeg_source_mgr {    // Nothing dynamic - cannot rely on destruction over longjump    FILE* stream;    JOCTET buffer[max_buf];public:    my_jpeg_source_mgr(FILE* new_stream);};extern "C" {static void dimjpeg_init_source(j_decompress_ptr){}static boolean dimjpeg_fill_input_buffer(j_decompress_ptr cinfo){  int num_read;  my_jpeg_source_mgr* src = (my_jpeg_source_mgr*)cinfo->src;  src->next_input_byte = src->buffer;  
  num_read = fread( src->buffer, 1, max_buf, src->stream);  if ( num_read <= 0 ) 
  {    // Insert a fake EOI marker - as per jpeglib recommendation    src->buffer[0] = (JOCTET) 0xFF;    src->buffer[1] = (JOCTET) JPEG_EOI;    src->bytes_in_buffer = 2;  } 
  else 
    src->bytes_in_buffer = num_read;
  return TRUE;}static void dimjpeg_skip_input_data(j_decompress_ptr cinfo, long num_bytes){  my_jpeg_source_mgr* src = (my_jpeg_source_mgr*)cinfo->src;  // `dumb' implementation from jpeglib  // Just a dumb implementation for now.  Could use fseek() except  // it doesn't work on pipes.  Not clear that being smart is worth  // any trouble anyway --- large skips are infrequent.  if (num_bytes > 0) 
  {    while (num_bytes > (long) src->bytes_in_buffer) 
    {      num_bytes -= (long) src->bytes_in_buffer;      (void) dimjpeg_fill_input_buffer(cinfo);      // note we assume that qt_fill_input_buffer will never return FALSE,      // so suspension need not be handled.    }    src->next_input_byte += (size_t) num_bytes;    src->bytes_in_buffer -= (size_t) num_bytes;  }}static void dimjpeg_term_source(j_decompress_ptr){}} // extern Cinline my_jpeg_source_mgr::my_jpeg_source_mgr(FILE* new_stream){  jpeg_source_mgr::init_source       = dimjpeg_init_source;  jpeg_source_mgr::fill_input_buffer = dimjpeg_fill_input_buffer;  jpeg_source_mgr::skip_input_data   = dimjpeg_skip_input_data;  jpeg_source_mgr::resync_to_restart = jpeg_resync_to_restart;  jpeg_source_mgr::term_source       = dimjpeg_term_source;  stream = new_stream;  bytes_in_buffer = 0;  next_input_byte = buffer;}*/


struct my_jpeg_source_mgr : public jpeg_source_mgr {
    // Nothing dynamic - cannot rely on destruction over longjump
    TDimFormatHandle *fmtHndl;
    JOCTET buffer[max_buf];

public:
    my_jpeg_source_mgr(TDimFormatHandle *new_hndl);
};

extern "C" {

static void dimjpeg_init_source(j_decompress_ptr)
{
}

static boolean dimjpeg_fill_input_buffer(j_decompress_ptr cinfo)
{
  int num_read;
  my_jpeg_source_mgr* src = (my_jpeg_source_mgr*)cinfo->src;
  src->next_input_byte = src->buffer;
  
  //num_read = fread( src->buffer, 1, max_buf, src->stream);
  num_read = dimRead( src->fmtHndl, src->buffer, 1, max_buf );

  if ( num_read <= 0 ) 
  {
    // Insert a fake EOI marker - as per jpeglib recommendation
    src->buffer[0] = (JOCTET) 0xFF;
    src->buffer[1] = (JOCTET) JPEG_EOI;
    src->bytes_in_buffer = 2;
  } 
  else 
    src->bytes_in_buffer = num_read;

  return TRUE;
}

static void dimjpeg_skip_input_data(j_decompress_ptr cinfo, long num_bytes)
{
  my_jpeg_source_mgr* src = (my_jpeg_source_mgr*)cinfo->src;

  // `dumb' implementation from jpeglib

  // Just a dumb implementation for now.  Could use fseek() except
  // it doesn't work on pipes.  Not clear that being smart is worth
  // any trouble anyway --- large skips are infrequent.
  if (num_bytes > 0) 
  {
    while (num_bytes > (long) src->bytes_in_buffer) 
    {
      num_bytes -= (long) src->bytes_in_buffer;
      (void) dimjpeg_fill_input_buffer(cinfo);
      // note we assume that qt_fill_input_buffer will never return FALSE,
      // so suspension need not be handled.
    }
    src->next_input_byte += (size_t) num_bytes;
    src->bytes_in_buffer -= (size_t) num_bytes;
  }
}

static void dimjpeg_term_source(j_decompress_ptr)
{
}

} // extern C


inline my_jpeg_source_mgr::my_jpeg_source_mgr(TDimFormatHandle *new_hndl)
{
  jpeg_source_mgr::init_source       = dimjpeg_init_source;
  jpeg_source_mgr::fill_input_buffer = dimjpeg_fill_input_buffer;
  jpeg_source_mgr::skip_input_data   = dimjpeg_skip_input_data;
  jpeg_source_mgr::resync_to_restart = jpeg_resync_to_restart;
  jpeg_source_mgr::term_source       = dimjpeg_term_source;
  fmtHndl = new_hndl;
  bytes_in_buffer = 0;
  next_input_byte = buffer;
}

//----------------------------------------------------------------------------
// READ PROC
//----------------------------------------------------------------------------
static int read_jpeg_image(TDimFormatHandle *fmtHndl)
{
  JSAMPROW row_pointer[1];
  TDimImageBitmap *image = fmtHndl->image;  struct jpeg_decompress_struct cinfo;  //struct my_jpeg_source_mgr *iod_src = new my_jpeg_source_mgr( fmtHndl->stream );
  struct my_jpeg_source_mgr *iod_src = new my_jpeg_source_mgr( fmtHndl );  struct my_error_mgr jerr;  jpeg_create_decompress(&cinfo);  cinfo.src = iod_src;  cinfo.err = jpeg_std_error(&jerr);  jerr.error_exit = my_error_exit;

  if (!setjmp(jerr.setjmp_buffer))   {
    (void) jpeg_read_header(&cinfo, TRUE);    (void) jpeg_start_decompress(&cinfo);

    if (allocImg( image, cinfo.output_width, cinfo.output_height, cinfo.output_components, 8 ) != 0) 
    {
      jpeg_destroy_decompress(&cinfo);      
      return 1;
    }
    if (cinfo.output_components == 1)    {      while (cinfo.output_scanline < cinfo.output_height)
      {        row_pointer[0] =  ((uchar *) image->bits[0]) + (cinfo.output_width*cinfo.output_scanline);
        (void) jpeg_read_scanlines( &cinfo, row_pointer, 1 );
      }    } // if 1 component    

    if ( cinfo.output_components == 3 ) 
    {
      row_pointer[0] = new uchar[cinfo.output_width*cinfo.output_components];

      while (cinfo.output_scanline < cinfo.output_height)
      {
        register unsigned int i;        
        (void) jpeg_read_scanlines( &cinfo, row_pointer, 1 );
        uchar *row = row_pointer[0];        
        uchar* pix1 = ((uchar *) image->bits[0]) + cinfo.output_width * (cinfo.output_scanline-1);
        uchar* pix2 = ((uchar *) image->bits[1]) + cinfo.output_width * (cinfo.output_scanline-1);
        uchar* pix3 = ((uchar *) image->bits[2]) + cinfo.output_width * (cinfo.output_scanline-1);

        for (i=0; i<cinfo.output_width; i++) 
        {
          *pix1++ = *row++;
          *pix2++ = *row++;
          *pix3++ = *row++;
        }

      } // while scanlines
      delete row_pointer[0];
    } // if 3 components

    if ( cinfo.output_components == 4 ) 
    {
      row_pointer[0] = new uchar[cinfo.output_width*cinfo.output_components];

      while (cinfo.output_scanline < cinfo.output_height)
      {
        register unsigned int i;        
        (void) jpeg_read_scanlines( &cinfo, row_pointer, 1 );
        uchar *row = row_pointer[0];        
        uchar* pix1 = ((uchar *) image->bits[0]) + cinfo.output_width * (cinfo.output_scanline-1);
        uchar* pix2 = ((uchar *) image->bits[1]) + cinfo.output_width * (cinfo.output_scanline-1);
        uchar* pix3 = ((uchar *) image->bits[2]) + cinfo.output_width * (cinfo.output_scanline-1);
        uchar* pix4 = ((uchar *) image->bits[3]) + cinfo.output_width * (cinfo.output_scanline-1);

        for (i=0; i<cinfo.output_width; i++) 
        {
          *pix1++ = *row++;
          *pix2++ = *row++;
          *pix3++ = *row++;
          *pix4++ = *row++;
        }

      } // while scanlines
      delete row_pointer[0];
    } // if 4 components

    (void) jpeg_finish_decompress(&cinfo);
  }
  jpeg_destroy_decompress(&cinfo);  delete iod_src;
  return 0;}

//****************************************************************************
// WRITE STUFF
//****************************************************************************
/*
struct my_jpeg_destination_mgr : public jpeg_destination_mgr {    // Nothing dynamic - cannot rely on destruction over longjump    FILE* stream;    JOCTET buffer[max_buf];public:    my_jpeg_destination_mgr(FILE* stream);};extern "C" {static void dimjpeg_init_destination(j_compress_ptr){}static void dimjpeg_exit_on_error(j_compress_ptr cinfo, FILE* stream){  // cinfo->err->msg_code = JERR_FILE_WRITE;  fflush( stream );
  (*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 ( fwrite((char*)dest->buffer, 1, max_buf, dest->stream) != max_buf )
    dimjpeg_exit_on_error(cinfo, dest->stream);

  fflush( dest->stream );  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 ( fwrite((char*)dest->buffer, 1, n, dest->stream) != n )
    dimjpeg_exit_on_error(cinfo, dest->stream);
  fflush( dest->stream );  dimjpeg_exit_on_error( cinfo, dest->stream );}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -