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

📄 dim_jpeg_format_io.cpp

📁 Digital Notebook Source Code v1.1.0 [
💻 CPP
📖 第 1 页 / 共 2 页
字号:
} // 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 + -