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

📄 tif_ojpeg.c

📁 一款最完整的工业组态软源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
    {
      TIFFTAG_JPEGCOLORMODE         ,0            ,0            ,
      TIFF_ANY      ,FIELD_PSEUDO                ,FALSE,FALSE,"JPEGColorMode"
    }
  };
static const char JPEGLib_name[]={"JPEG Library"},
                  bad_bps[]={"%u BitsPerSample not allowed for JPEG"},
                  bad_photometry[]={"PhotometricInterpretation %u not allowed for JPEG"},
                  bad_subsampling[]={"invalid YCbCr subsampling factor(s)"},
#                 ifdef never
                  no_write_frac[]={"fractional scan line discarded"},
#                 endif
                  no_read_frac[]={"fractional scan line not read"},
                  no_jtable_space[]={"No space for JPEGTables"};

/* The following diagnostic subroutines interface with and replace default
   subroutines in the JPEG Library.  Our basic strategy is to use "setjmp()"/
   "longjmp()" in order to return control to the TIFF Library when the JPEG
   library detects an error, and to use TIFF Library subroutines for displaying
   diagnostic messages to a client application.
*/
static void
TIFFojpeg_error_exit(register j_common_ptr cinfo)
{
    char buffer[JMSG_LENGTH_MAX];
    int code = cinfo->err->msg_code;

    if (((OJPEGState *)cinfo)->is_WANG) {
	if (code == JERR_SOF_DUPLICATE || code == JERR_SOI_DUPLICATE)
	    return;	    /* ignore it */
    }

    (*cinfo->err->format_message)(cinfo,buffer);
    TIFFError(JPEGLib_name,buffer); /* Display error message */
    jpeg_abort(cinfo); /* Clean up JPEG Library state */
    LONGJMP(((OJPEGState *)cinfo)->exit_jmpbuf,1); /* Return to TIFF client */
}

static void
TIFFojpeg_output_message(register j_common_ptr cinfo)
  { char buffer[JMSG_LENGTH_MAX];

 /* This subroutine is invoked only for warning messages, since the JPEG
    Library's "error_exit" method does its own thing and "trace_level" is never
    set > 0.
 */
    (*cinfo->err->format_message)(cinfo,buffer);
    TIFFWarning(JPEGLib_name,buffer);
  }

/* The following subroutines, which also interface with the JPEG Library, exist
   mainly in limit the side effects of "setjmp()" and convert JPEG normal/error
   conditions into TIFF Library return codes.
*/
#define CALLJPEG(sp,fail,op)(SETJMP((sp)->exit_jmpbuf)?(fail):(op))
#define CALLVJPEG(sp,op)CALLJPEG(sp,0,((op),1))
#ifdef never

static int
TIFFojpeg_create_compress(register OJPEGState *sp)
  {
    sp->cinfo.c.err = jpeg_std_error(&sp->err); /* Initialize error handling */
    sp->err.error_exit = TIFFojpeg_error_exit;
    sp->err.output_message = TIFFojpeg_output_message;
    return CALLVJPEG(sp,jpeg_create_compress(&sp->cinfo.c));
  }

/* The following subroutines comprise a JPEG Library "destination" data manager
   by directing compressed data from the JPEG Library to a TIFF Library output
   buffer.
*/
static void
std_init_destination(register j_compress_ptr cinfo){} /* "Dummy" stub */

static boolean
std_empty_output_buffer(register j_compress_ptr cinfo)
  {
#   define sp ((OJPEGState *)cinfo)
    register TIFF *tif = sp->tif;

    tif->tif_rawcc = tif->tif_rawdatasize; /* Entire buffer has been filled */
    TIFFFlushData1(tif);
    sp->dest.next_output_byte = (JOCTET *)tif->tif_rawdata;
    sp->dest.free_in_buffer = (size_t)tif->tif_rawdatasize;
    return TRUE;
#   undef sp
  }

static void
std_term_destination(register j_compress_ptr cinfo)
  {
#   define sp ((OJPEGState *)cinfo)
    register TIFF *tif = sp->tif;

 /* NB: The TIFF Library does the final buffer flush. */
    tif->tif_rawcp = (tidata_t)sp->dest.next_output_byte;
    tif->tif_rawcc = tif->tif_rawdatasize - (tsize_t)sp->dest.free_in_buffer;
#   undef sp
  }

/* Alternate destination manager to output JPEGTables field: */

static void
tables_init_destination(register j_compress_ptr cinfo)
  {
#   define sp ((OJPEGState *)cinfo)
 /* The "jpegtables_length" field is the allocated buffer size while building */
    sp->dest.next_output_byte = (JOCTET *)sp->jpegtables;
    sp->dest.free_in_buffer = (size_t)sp->jpegtables_length;
#   undef sp
  }

static boolean
tables_empty_output_buffer(register j_compress_ptr cinfo)
  { void *newbuf;
#   define sp ((OJPEGState *)cinfo)

 /* The entire buffer has been filled, so enlarge it by 1000 bytes. */
    if (!( newbuf = _TIFFrealloc( (tdata_t)sp->jpegtables
                                , (tsize_t)(sp->jpegtables_length + 1000)
                                )
         )
       ) ERREXIT1(cinfo,JERR_OUT_OF_MEMORY,100);
    sp->dest.next_output_byte = (JOCTET *)newbuf + sp->jpegtables_length;
    sp->dest.free_in_buffer = (size_t)1000;
    sp->jpegtables = newbuf;
    sp->jpegtables_length += 1000;
    return TRUE;
#   undef sp
  }

static void
tables_term_destination(register j_compress_ptr cinfo)
  {
#   define sp ((OJPEGState *)cinfo)
 /* Set tables length to no. of Bytes actually emitted. */
    sp->jpegtables_length -= sp->dest.free_in_buffer;
#   undef sp
  }

/*ARGSUSED*/ static int
TIFFojpeg_tables_dest(register OJPEGState *sp, TIFF *tif)
  {

 /* Allocate a working buffer for building tables.  The initial size is 1000
    Bytes, which is usually adequate.
 */
    if (sp->jpegtables) _TIFFfree(sp->jpegtables);
    if (!(sp->jpegtables = (void*)
                           _TIFFmalloc((tsize_t)(sp->jpegtables_length = 1000))
         )
       )
      {
        sp->jpegtables_length = 0;
        TIFFError("TIFFojpeg_tables_dest",no_jtable_space);
        return 0;
      };
    sp->cinfo.c.dest = &sp->dest;
    sp->dest.init_destination = tables_init_destination;
    sp->dest.empty_output_buffer = tables_empty_output_buffer;
    sp->dest.term_destination = tables_term_destination;
    return 1;
  }
#else /* well, hardly ever */

static int
_notSupported(register TIFF *tif)
  { const TIFFCodec *c = TIFFFindCODEC(tif->tif_dir.td_compression);

    TIFFError(tif->tif_name,"%s compression not supported",c->name);
    return 0;
  }
#endif /* never */

/* The following subroutines comprise a JPEG Library "source" data manager by
   by directing compressed data to the JPEG Library from a TIFF Library input
   buffer.
*/
static void
std_init_source(register j_decompress_ptr cinfo)
  {
#   define sp ((OJPEGState *)cinfo)
    register TIFF *tif = sp->tif;

    if (sp->src.bytes_in_buffer == 0)
      {
        sp->src.next_input_byte = (const JOCTET *)tif->tif_rawdata;
        sp->src.bytes_in_buffer = (size_t)tif->tif_rawcc;
      };
#   undef sp
  }

static boolean
std_fill_input_buffer(register j_decompress_ptr cinfo)
  { static const JOCTET dummy_EOI[2]={0xFF,JPEG_EOI};
#   define sp ((OJPEGState *)cinfo)

 /* Control should never get here, since an entire strip/tile is read into
    memory before the decompressor is called; thus, data should have been
    supplied by the "init_source" method.  ...But, sometimes things fail.
 */
    WARNMS(cinfo,JWRN_JPEG_EOF);
    sp->src.next_input_byte = dummy_EOI; /* Insert a fake EOI marker */
    sp->src.bytes_in_buffer = sizeof dummy_EOI;
    return TRUE;
#   undef sp
  }

static void
std_skip_input_data(register j_decompress_ptr cinfo, long num_bytes)
  {
#   define sp ((OJPEGState *)cinfo)

    if (num_bytes > 0)
    {
      if (num_bytes > (long)sp->src.bytes_in_buffer) /* oops: buffer overrun */
        (void)std_fill_input_buffer(cinfo);
      else
        {
          sp->src.next_input_byte += (size_t)num_bytes;
          sp->src.bytes_in_buffer -= (size_t)num_bytes;
        }
    }
#   undef sp
  }

/*ARGSUSED*/ static void
std_term_source(register j_decompress_ptr cinfo){} /* "Dummy" stub */

/* Allocate temporary I/O buffers for downsampled data, using values computed in
   "jpeg_start_{de}compress()".  We use the JPEG Library's allocator so that
   buffers will be released automatically when done with a strip/tile.  This is
   also a handy place to compute samplesperclump, bytesperline, etc.
*/
static int
alloc_downsampled_buffers(TIFF *tif,jpeg_component_info *comp_info,
                          int num_components)
  { register OJPEGState *sp = OJState(tif);

    sp->samplesperclump = 0;
    if (num_components > 0)
      { tsize_t size = sp->cinfo.comm.is_decompressor
#                    ifdef D_LOSSLESS_SUPPORTED
                     ? sp->cinfo.d.min_codec_data_unit
#                    else
                     ? DCTSIZE
#                    endif
#                    ifdef C_LOSSLESS_SUPPORTED
                     : sp->cinfo.c.data_unit;
#                    else
                     : DCTSIZE;
#                    endif
        int ci = 0;
        register jpeg_component_info *compptr = comp_info;

        do
          { JSAMPARRAY buf;

            sp->samplesperclump +=
              compptr->h_samp_factor * compptr->v_samp_factor;
#           if defined(C_LOSSLESS_SUPPORTED) || defined(D_LOSSLESS_SUPPORTED)
            if (!(buf = CALLJPEG(sp,0,(*sp->cinfo.comm.mem->alloc_sarray)(&sp->cinfo.comm,JPOOL_IMAGE,compptr->width_in_data_units*size,compptr->v_samp_factor*size))))
#           else
            if (!(buf = CALLJPEG(sp,0,(*sp->cinfo.comm.mem->alloc_sarray)(&sp->cinfo.comm,JPOOL_IMAGE,compptr->width_in_blocks*size,compptr->v_samp_factor*size))))
#           endif
              return 0;
            sp->ds_buffer[ci] = buf;
          }
        while (++compptr,++ci < num_components);
      };
    return 1;
  }
#ifdef never

/* JPEG Encoding begins here. */

/*ARGSUSED*/ static int
OJPEGEncode(register TIFF *tif,tidata_t buf,tsize_t cc,tsample_t s)
  { tsize_t rows;                          /* No. of unprocessed rows in file */
    register OJPEGState *sp = OJState(tif);

 /* Encode a chunk of pixels, where returned data is NOT down-sampled (the
    standard case).  The data is expected to be written in scan-line multiples.
 */
    if (cc % sp->bytesperline) TIFFWarning(tif->tif_name,no_write_frac);
    if ( (cc /= bytesperline)      /* No. of complete rows in caller's buffer */
       > (rows = sp->cinfo.c.image_height - sp->cinfo.c.next_scanline)
       ) cc = rows;
    while (--cc >= 0)
      {
        if (   CALLJPEG(sp,-1,jpeg_write_scanlines(&sp->cinfo.c,(JSAMPARRAY)&buf,1))
            != 1
           ) return 0;
        ++tif->tif_row;
        buf += sp->bytesperline;
      };
    return 1;
  }

/*ARGSUSED*/ static int
OJPEGEncodeRaw(register TIFF *tif,tidata_t buf,tsize_t cc,tsample_t s)
  { tsize_t rows;                          /* No. of unprocessed rows in file */
    JDIMENSION lines_per_MCU, size;
    register OJPEGState *sp = OJState(tif);

 /* Encode a chunk of pixels, where returned data is down-sampled as per the
    sampling factors.  The data is expected to be written in scan-line

⌨️ 快捷键说明

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