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

📄 tif_ojpeg.c

📁 君正早期ucos系统(只有早期的才不没有打包成库),MPLAYER,文件系统,图片解码,浏览,电子书,录音,想学ucos,识货的人就下吧 russblock fmradio explore set
💻 C
📖 第 1 页 / 共 5 页
字号:
    sp->src.skip_input_data = std_skip_input_data;
    sp->src.resync_to_restart = jpeg_resync_to_restart;
    sp->src.term_source = std_term_source;
    tif->tif_postdecode = _TIFFNoPostDecode; /* Override Byte-swapping */
    return 1;
#   undef td
  }

/*ARGSUSED*/ static int
OJPEGDecode(register TIFF *tif,tidata_t buf,tsize_t cc,tsample_t s)
  { static float zeroes[6];
    tsize_t nrows;
    register OJPEGState *sp = OJState(tif);

 /* BEWARE OF KLUDGE:  If our input file was produced by Microsoft's Wang
                       Imaging for Windows application, the DC coefficients of
    each JPEG image component (Y,Cb,Cr) must be reset at the beginning of each
    TIFF "strip", and any JPEG data bits remaining in the decoder's input buffer
    must be discarded, up to the next input-Byte storage boundary.  To do so, we
    create an "ad hoc" interface in the "jdhuff.c" module of IJG JPEG Library
    Version 6, and we invoke that interface here before decoding each "strip".
 */
    if (sp->is_WANG) jpeg_reset_huff_decode(&sp->cinfo.d,zeroes);

 /* Decode a chunk of pixels, where returned data is NOT down-sampled (the
    standard case).  The data is expected to be read in scan-line multiples.
 */
    if (nrows = sp->cinfo.d.image_height)
      { unsigned int bytesperline = isTiled(tif)
                                  ? TIFFTileRowSize(tif)
                                  : TIFFScanlineSize(tif);

     /* WARNING:  Unlike "OJPEGDecodeRaw()", below, the no. of Bytes in each
                  decoded row is calculated here as "bytesperline" instead of
        using "sp->bytesperline", which might be a little smaller.  This can
        occur for an old tiled image whose width isn't a multiple of 8 pixels.
        That's illegal according to the TIFF Version 6 specification, but some
        test files, like "zackthecat.tif", were built that way.  In those cases,
        we want to embed the image's true width in our caller's buffer (which is
        presumably allocated according to the expected tile width) by
        effectively "padding" it with unused Bytes at the end of each row.
     */
        do
          { JSAMPROW bufptr = (JSAMPROW)buf;

            if (TIFFojpeg_read_scanlines(sp,&bufptr,1) != 1) return 0;
            buf += bytesperline;
            ++tif->tif_row;
          }
        while ((cc -= bytesperline) > 0 && --nrows > 0);
      };
    return sp->cinfo.d.output_scanline < sp->cinfo.d.output_height
        || TIFFojpeg_finish_decompress(sp);
  }

/*ARGSUSED*/ static int
OJPEGDecodeRaw(register TIFF *tif,tidata_t buf,tsize_t cc,tsample_t s)
  { static float zeroes[6];
    tsize_t nrows;
    register OJPEGState *sp = OJState(tif);

 /* BEWARE OF KLUDGE:  If our input file was produced by Microsoft's Wang
                       Imaging for Windows application, the DC coefficients of
    each JPEG image component (Y,Cb,Cr) must be reset at the beginning of each
    TIFF "strip", and any JPEG data bits remaining in the decoder's input buffer
    must be discarded, up to the next input-Byte storage boundary.  To do so, we
    create an "ad hoc" interface in the "jdhuff.c" module of IJG JPEG Library
    Version 6, and we invoke that interface here before decoding each "strip".
 */
    if (sp->is_WANG) jpeg_reset_huff_decode(&sp->cinfo.d,zeroes);

 /* Decode a chunk of pixels, where returned data is down-sampled as per the
    sampling factors.  The data is expected to be read in scan-line multiples.
 */
    if (nrows = sp->cinfo.d.image_height)
      do
        {
          if (sp->scancount >= DCTSIZE) /* reload downsampled-data buffer */
            { int n = sp->cinfo.d.max_v_samp_factor*DCTSIZE;

              if (TIFFojpeg_read_raw_data(sp,sp->ds_buffer,n) != n) return 0;
              sp->scancount = 0;
            };
          if (sp->cinfo.d.num_components > 0)
            { int ci = 0, clumpoffset = 0;
              register jpeg_component_info *compptr = sp->cinfo.d.comp_info;

           /* The fastest way to separate the data is: make 1 pass over the scan
              line for each row of each component.
           */
              do
                { int ypos = 0;

                  if (compptr->h_samp_factor == 1) /* Cb & Cr fast path */
                    do
                      { register JSAMPLE *inptr =
                          sp->ds_buffer[ci][sp->scancount*compptr->v_samp_factor+ypos],
                                         *outptr = (JSAMPLE *)buf + clumpoffset;
                     /* Cb & Cr have sampling factors = 1, so this is correct */
                        register int clumps_per_line =
                          sp->cinfo.d.comp_info[1].downsampled_width;

                        do *outptr = *inptr++;
                        while ( (outptr += sp->samplesperclump)
                              , --clumps_per_line > 0
                              );
                      }
                    while ( (clumpoffset += compptr->h_samp_factor)
                          , ++ypos < compptr->v_samp_factor
                          );
                  else /* general case */
                    do
                      { register JSAMPLE *inptr =
                          sp->ds_buffer[ci][sp->scancount*compptr->v_samp_factor+ypos],
                                         *outptr = (JSAMPLE *)buf + clumpoffset;
                     /* Cb & Cr have sampling factors = 1, so this is correct */
                        register int clumps_per_line =
                          sp->cinfo.d.comp_info[1].downsampled_width;

                        do
                          { register int xpos = 0;

                            do outptr[xpos] = *inptr++;
                            while (++xpos < compptr->h_samp_factor);
                          }
                        while ( (outptr += sp->samplesperclump)
                              , --clumps_per_line > 0
                              );
                      }
                    while ( (clumpoffset += compptr->h_samp_factor)
                          , ++ypos < compptr->v_samp_factor
                          );
                }
              while (++compptr,++ci < sp->cinfo.d.num_components);
            };
          ++sp->scancount;
          buf += sp->bytesperline;
          ++tif->tif_row;
        }
      while ((cc -= sp->bytesperline) > 0 && --nrows > 0);
    return sp->cinfo.d.output_scanline < sp->cinfo.d.output_height
        || TIFFojpeg_finish_decompress(sp);
  }

/* "OJPEGPreDecode()" temporarily forces the JPEG Library to use the following
   subroutine as a "dummy" input reader, to fool it into thinking that it has
   read the image's 1st "Start of Scan" (SOS) marker and initialize accordingly.
*/
/*ARGSUSED*/ METHODDEF(int)
fake_SOS_marker(j_decompress_ptr cinfo){return JPEG_REACHED_SOS;}

/*ARGSUSED*/ METHODDEF(int)
suspend(j_decompress_ptr cinfo){return JPEG_SUSPENDED;}

/*ARGSUSED*/ static int
OJPEGPreDecode(register TIFF *tif,tsample_t s)
  { static const char bad_factors[]={"Improper JPEG sampling factors"},
                      module[]={"OJPEGPreDecode"};
    uint32 segment_width, segment_height;
    int downsampled_output = FALSE,
        is_JFIF;                                           /* <=> JFIF image? */
    J_COLOR_SPACE in_color_space = JCS_UNKNOWN;  /* Image's input color space */
    register OJPEGState *sp = OJState(tif);
#   define td (&tif->tif_dir)

    tif->tif_predecode = _TIFFNoPreCode; /* Don't call us again */

 /* BOGOSITY ALERT!  MicroSoft's Wang Imaging for Windows application produces
                     images containing "JPEGInterchangeFormat[Length]" TIFF
    records that resemble JFIF-in-TIFF encapsulations but, in fact, violate the
    TIFF Version 6 specification in several ways; nevertheless, we try to handle
    them gracefully because there are apparently a lot of them around.  The
    purported "JFIF" data stream in one of these files vaguely resembles a JPEG
    "tables only" data stream, except that there's no trailing EOI marker.  The
    rest of the JPEG data stream lies in a discontiguous file region, identified
    by the 0th Strip offset (which is *also* illegal!), where it begins with an
    SOS marker and apparently continues to the end of the file.  There is no
    trailing EOI marker here, either.
 */
    is_JFIF = !sp->is_WANG && TIFFFieldSet(tif,FIELD_JPEGIFOFFSET);

 /* Set up to decode a strip or tile.  Start by resetting decoder state left
    over from any previous strip/tile, in case our client application didn't
    read all of that data.  Then read the JPEG header data.
 */
    if (!TIFFojpeg_abort(sp)) return 0;

 /* Do a preliminary translation of the image's (input) color space from its
    TIFF representation to JPEG Library representation.  We might have to fix
    this up after calling "TIFFojpeg_read_header()", which tries to establish
    its own JPEG Library defaults.  While we're here, initialize some other
    decompression parameters that won't be overridden.
 */
    if (td->td_planarconfig == PLANARCONFIG_CONTIG)
      {
        if (sp->h_sampling != 1 || sp->v_sampling != 1)
          downsampled_output = TRUE; /* Tentative default */
        switch (sp->photometric) /* default color-space translation */
          {
            case PHOTOMETRIC_MINISBLACK: in_color_space = JCS_GRAYSCALE;
                                         break;
            case PHOTOMETRIC_RGB       : in_color_space = JCS_RGB;
                                         break;
            case PHOTOMETRIC_SEPARATED : in_color_space = JCS_CMYK;
                                         break;
            case PHOTOMETRIC_YCBCR     : in_color_space = JCS_YCbCr;
                                      /* JPEG Library converts YCbCr to RGB? */
                                         if (   sp->jpegcolormode
                                             == JPEGCOLORMODE_RGB
                                            ) downsampled_output = FALSE;
          }
      };
    segment_width = td->td_imagewidth;
    segment_height = td->td_imagelength - tif->tif_row;
    if (isTiled(tif))
      {
        if (sp->is_WANG) /* we don't know how to handle it */
          {
            TIFFError(module,"Tiled Wang image not supported");
            return 0;
          };

     /* BOGOSITY ALERT!  "TIFFTileRowSize()" seems to work fine for modern JPEG-
                         in-TIFF encapsulations where the image width--like the
        tile width--is a multiple of 8 or 16 pixels.  But image widths and
        heights are aren't restricted to 8- or 16-bit multiples, and we need
        the exact Byte count of decompressed scan lines when we call the JPEG
        Library.  At least one old file ("zackthecat.tif") in the TIFF Library
        test suite has widths and heights slightly less than the tile sizes, and
        it apparently used the bogus computation below to determine the number
        of Bytes per scan line (was this due to an old, broken version of
        "TIFFhowmany()"?).  Before we get here, "OJPEGSetupDecode()" verified
        that our image uses 8-bit samples, so the following check appears to
        return the correct answer in all known cases tested to date.
     */
        if (is_JFIF || (segment_width & 7) == 0)
          sp->bytesperline = TIFFTileRowSize(tif); /* Normal case */
        else
          {
            /* Was the file-encoder's segment-width calculation bogus? */
            segment_width = (segment_width/sp->h_sampling + 1) * sp->h_sampling;
            sp->bytesperline = segment_width * td->td_samplesperpixel;
          }
      }
    else sp->bytesperline = TIFFVStripSize(tif,1);
    if (td->td_planarconfig == PLANARCONFIG_SEPARATE && s > 0)
      {

     /* Scale the expected strip/tile size to match a downsampled component. */

        segment_width = TIFFhowmany(segment_width,sp->h_sampling);
        segment_height = TIFFhowmany(segment_height,sp->v_sampling);
      };

 /* BEWARE OF KLUDGE:  If we have JPEG Interchange File Format (JFIF) image,
                       then we want to read "metadata" in the bit-stream's
    header and validate it against corresponding information in TIFF records.
    But if we have a *really old* JPEG file that's not JFIF, then we simply
    assign TIFF-record values to JPEG Library variables without checking.
 */
    if (is_JFIF) /* JFIF image */
      { unsigned char *end_of_data;
        register unsigned char *p;

     /* WARNING:  Although the image file contains a JFIF bit stream, it might
                  also contain some old TIFF records causing "OJPEGVSetField()"
        to have allocated quantization or Huffman decoding tables.  But when the
        JPEG Library reads and parses the JFIF header below, it reallocate these
        tables anew without checking for "dangling" pointers, thereby causing a
        memory "leak".  We have enough information to potentially deallocate the
        old tables here, but unfortunately JPEG Library Version 6B uses a "pool"
        allocator for small objects, with no deallocation procedure; instead, it
        reclaims a whole pool when an image is closed/destroyed, so well-behaved
        TIFF client applications (i.e., those which close their JPEG images as
        soon as they're no longer needed) will waste memory for a short time but
        recover it eventually.  But ill-behaved TIFF clients (i.e., those which
        keep many JPEG images open gratuitously) can exhaust memory prematurely.
        If the JPEG Library ever implements a deallocation procedure, insert
        this clean-up code:
     */
#       ifdef someday
        if (sp->jpegtablesmode & JPEGTABLESMODE_QUANT) /* free quant. tables */
          { register int i = 0;

            do
              { register JQUANT_TBL *q;

                if (q = sp->cinfo.d.quant_tbl_ptrs[i])
                  {
                    jpeg_free_small(&sp->cinfo.comm,q,sizeof *q);
                    sp->cinfo.d.quant_tbl_ptrs[i] = 0;
                  }
              }
            while (++i < NUM_QUANT_TBLS);
          };
        if (sp->jpegtablesmode & JPEGTABLESMODE_HUFF) /* free Huffman tables */
          { register int i = 0;

            do
              { register JHUFF_TBL *h;

                if (h = sp->cinfo.d.dc_huff_tbl_ptrs[i])
                  {
                    jpeg_free_small(&sp->cinfo.comm,h,sizeof *h);
                    sp->cinfo.d.dc_huff_tbl_ptrs[i] = 0;
                  };
                if (h = sp->cinfo.d.ac_huff_tbl_ptrs[i])
                  {
                    jpeg_free_small(&sp->cinfo.comm,h,sizeof *h);
                    sp->cinfo.d.ac_huff_tbl_ptrs[i] = 0;
                  }
              }
            while (++i < NUM_HUFF_TBLS);
          };
#       endif /* someday */

     /* Since we might someday wish to try rewriting "old format" JPEG-in-TIFF

⌨️ 快捷键说明

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