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

📄 tif_ojpeg.c

📁 开源组态软件
💻 C
📖 第 1 页 / 共 5 页
字号:
    multiples.
 */
    cc /= sp->bytesperline;
    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;
#   ifdef C_LOSSLESS_SUPPORTED
    lines_per_MCU = sp->cinfo.c.max_samp_factor*(size = sp->cinfo.d.data_unit);
#   else
    lines_per_MCU = sp->cinfo.c.max_samp_factor*(size = DCTSIZE);
#   endif
    while (--cc >= 0)
      { int ci = 0, clumpoffset = 0;
        register jpeg_component_info *compptr = sp->cinfo.c.comp_info;

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

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

                padding = (int)
#                         ifdef C_LOSSLESS_SUPPORTED
                          ( compptr->width_in_data_units * size
#                         else
                          ( compptr->width_in_blocks * size
#                         endif
                          - clumps_per_line * compptr->h_samp_factor
                          );
                if (compptr->h_samp_factor == 1) /* Cb & Cr fast path */
                  do *outptr++ = *inptr;
                  while ((inptr += sp->samplesperclump),--clumps_per_line > 0);
                else /* general case */
                  do
                    {
                      xpos = 0;
                      do *outptr++ = inptr[xpos];
                      while (++xpos < compptr->h_samp_factor);
                    }
                  while ((inptr += sp->samplesperclump),--clumps_per_line > 0);
                xpos = 0; /* Pad each scan line as needed */
                do outptr[0] = outptr[-1]; while (++outptr,++xpos < padding);
                clumpoffset += compptr->h_samp_factor;
              }
            while (++ypos < compptr->v_samp_factor);
          }
        while (++compptr,++ci < sp->cinfo.c.num_components);
        if (++sp->scancount >= size)
          {
            if (   CALLJPEG(sp,-1,jpeg_write_raw_data(&sp->cinfo.c,sp->ds_buffer,lines_per_MCU))
                != lines_per_MCU
               ) return 0;
            sp->scancount = 0;
          };
        ++tif->tif_row++
        buf += sp->bytesperline;
      };
    return 1;
  }

static int
OJPEGSetupEncode(register TIFF *tif)
  { static const char module[]={"OJPEGSetupEncode"};
    uint32 segment_height, segment_width;
    int status = 1;                              /* Assume success by default */
    register OJPEGState *sp = OJState(tif);
#   define td (&tif->tif_dir)

 /* Verify miscellaneous parameters.  This will need work if the TIFF Library
    ever supports different depths for different components, or if the JPEG
    Library ever supports run-time depth selection.  Neither seems imminent.
 */
    if (td->td_bitspersample != 8)
      {
        TIFFError(module,bad_bps,td->td_bitspersample);
        status = 0;
      };

 /* The TIFF Version 6.0 specification and IJG JPEG Library accept different
    sets of color spaces, so verify that our image belongs to the common subset
    and map its photometry code, then initialize to handle subsampling and
    optional JPEG Library YCbCr <-> RGB color-space conversion.
 */
    switch (td->td_photometric)
      {
        case PHOTOMETRIC_YCBCR     :

       /* ISO IS 10918-1 requires that JPEG subsampling factors be 1-4, but
          TIFF Version 6.0 is more restrictive: only 1, 2, and 4 are allowed.
       */
          if (   (   td->td_ycbcrsubsampling[0] == 1
                  || td->td_ycbcrsubsampling[0] == 2
                  || td->td_ycbcrsubsampling[0] == 4
                 )
              && (   td->td_ycbcrsubsampling[1] == 1
                  || td->td_ycbcrsubsampling[1] == 2
                  || td->td_ycbcrsubsampling[1] == 4
                 )
             )
            sp->cinfo.c.raw_data_in =
              ( (sp->h_sampling = td->td_ycbcrsubsampling[0]) << 3
              | (sp->v_sampling = td->td_ycbcrsubsampling[1])
              ) != 011;
          else
            {
              TIFFError(module,bad_subsampling);
              status = 0;
            };

       /* A ReferenceBlackWhite field MUST be present, since the default value
          is inapproriate for YCbCr.  Fill in the proper value if the
          application didn't set it.
       */
          if (!TIFFFieldSet(tif,FIELD_REFBLACKWHITE))
            { float refbw[6];
              long top = 1L << td->td_bitspersample;
 
              refbw[0] = 0;
              refbw[1] = (float)(top-1L);
              refbw[2] = (float)(top>>1);
              refbw[3] = refbw[1];
              refbw[4] = refbw[2];
              refbw[5] = refbw[1];
              TIFFSetField(tif,TIFFTAG_REFERENCEBLACKWHITE,refbw);
            };
          sp->cinfo.c.jpeg_color_space = JCS_YCbCr;
          if (sp->jpegcolormode == JPEGCOLORMODE_RGB)
            {
              sp->cinfo.c.raw_data_in = FALSE;
              sp->in_color_space = JCS_RGB;
              break;
            };
          goto L2;
        case PHOTOMETRIC_MINISBLACK:
          sp->cinfo.c.jpeg_color_space = JCS_GRAYSCALE;
          goto L1;
        case PHOTOMETRIC_RGB       :
          sp->cinfo.c.jpeg_color_space = JCS_RGB;
          goto L1;
        case PHOTOMETRIC_SEPARATED :
          sp->cinfo.c.jpeg_color_space = JCS_CMYK;
      L1: sp->jpegcolormode = JPEGCOLORMODE_RAW; /* No JPEG Lib. conversion */
      L2: sp->cinfo.d.in_color_space = sp->cinfo.d.jpeg_color-space;
          break;
        default                    :
          TIFFError(module,bad_photometry,td->td_photometric);
          status = 0;
      };
    tif->tif_encoderow = tif->tif_encodestrip = tif->tif_encodetile =
      sp->cinfo.c.raw_data_in ? OJPEGEncodeRaw : OJPEGEncode;
    if (isTiled(tif))
      { tsize_t size;

#       ifdef C_LOSSLESS_SUPPORTED
        if ((size = sp->v_sampling*sp->cinfo.c.data_unit) < 16) size = 16;
#       else
        if ((size = sp->v_sampling*DCTSIZE) < 16) size = 16;
#       endif
        if ((segment_height = td->td_tilelength) % size)
          {
            TIFFError(module,"JPEG tile height must be multiple of %d",size);
            status = 0;
          };
#       ifdef C_LOSSLESS_SUPPORTED
        if ((size = sp->h_sampling*sp->cinfo.c.data_unit) < 16) size = 16;
#       else
        if ((size = sp->h_sampling*DCTSIZE) < 16) size = 16;
#       endif
        if ((segment_width = td->td_tilewidth) % size)
          {
            TIFFError(module,"JPEG tile width must be multiple of %d",size);
            status = 0;
          };
        sp->bytesperline = TIFFTileRowSize(tif);
      }
    else
      { tsize_t size;

#       ifdef C_LOSSLESS_SUPPORTED
        if ((size = sp->v_sampling*sp->cinfo.c.data_unit) < 16) size = 16;
#       else
        if ((size = sp->v_sampling*DCTSIZE) < 16) size = 16;
#       endif
        if (td->td_rowsperstrip < (segment_height = td->td_imagelength))
          {
            if (td->td_rowsperstrip % size)
              {
                TIFFError(module,"JPEG RowsPerStrip must be multiple of %d",size);
                status = 0;
              };
            segment_height = td->td_rowsperstrip;
          };
        segment_width = td->td_imagewidth;
        sp->bytesperline = tif->tif_scanlinesize;
      };
    if (segment_width > 65535 || segment_height > 65535)
      {
        TIFFError(module,"Strip/tile too large for JPEG");
        status = 0;
      };

 /* Initialize all JPEG parameters to default values.  Note that the JPEG
    Library's "jpeg_set_defaults()" method needs legal values for the
    "in_color_space" and "input_components" fields.
 */
    sp->cinfo.c.input_components = 1; /* Default for JCS_UNKNOWN */
    if (!CALLVJPEG(sp,jpeg_set_defaults(&sp->cinfo.c))) status = 0;
    switch (sp->jpegtablesmode & (JPEGTABLESMODE_HUFF|JPEGTABLESMODE_QUANT))
      { register JHUFF_TBL *htbl;
        register JQUANT_TBL *qtbl;

        case 0                                       :
          sp->cinfo.c.optimize_coding = TRUE;
        case JPEGTABLESMODE_HUFF                     :
          if (!CALLVJPEG(sp,jpeg_set_quality(&sp->cinfo.c,sp->jpegquality,FALSE)))
            return 0;
          if (qtbl = sp->cinfo.c.quant_tbl_ptrs[0]) qtbl->sent_table = FALSE;
          if (qtbl = sp->cinfo.c.quant_tbl_ptrs[1]) qtbl->sent_table = FALSE;
          goto L3;
        case JPEGTABLESMODE_QUANT                    :
          sp->cinfo.c.optimize_coding = TRUE;

       /* We do not support application-supplied JPEG tables, so mark the field
          "not present".
       */
      L3: TIFFClrFieldBit(tif,FIELD_JPEGTABLES);
          break;
        case JPEGTABLESMODE_HUFF|JPEGTABLESMODE_QUANT:
          if (   !CALLVJPEG(sp,jpeg_set_quality(&sp->cinfo.c,sp->jpegquality,FALSE))
              || !CALLVJPEG(sp,jpeg_suppress_tables(&sp->cinfo.c,TRUE))
             )
            {
              status = 0;
              break;
            };
          if (qtbl = sp->cinfo.c.quant_tbl_ptrs[0]) qtbl->sent_table = FALSE;
          if (htbl = sp->cinfo.c.dc_huff_tbl_ptrs[0]) htbl->sent_table = FALSE;
          if (htbl = sp->cinfo.c.ac_huff_tbl_ptrs[0]) htbl->sent_table = FALSE;
          if (sp->cinfo.c.jpeg_color_space == JCS_YCbCr)
            {
              if (qtbl = sp->cinfo.c.quant_tbl_ptrs[1])
                qtbl->sent_table = FALSE;
              if (htbl = sp->cinfo.c.dc_huff_tbl_ptrs[1])
                htbl->sent_table = FALSE;
              if (htbl = sp->cinfo.c.ac_huff_tbl_ptrs[1])
                htbl->sent_table = FALSE;
            };
          if (   TIFFojpeg_tables_dest(sp,tif)
              && CALLVJPEG(sp,jpeg_write_tables(&sp->cinfo.c))
             )
            {
    
           /* Mark the field "present".  We can't use "TIFFSetField()" because
              "BEENWRITING" is already set!
           */
              TIFFSetFieldBit(tif,FIELD_JPEGTABLES);
              tif->tif_flags |= TIFF_DIRTYDIRECT;
            }
          else status = 0;
      };
    if (   sp->cinfo.c.raw_data_in
        && !alloc_downsampled_buffers(tif,sp->cinfo.c.comp_info,
                                      sp->cinfo.c.num_components)
       ) status = 0;
    if (status == 0) return 0; /* If TIFF errors, don't bother to continue */
 /* Grab parameters that are same for all strips/tiles. */

    sp->dest.init_destination = std_init_destination;
    sp->dest.empty_output_buffer = std_empty_output_buffer;
    sp->dest.term_destination = std_term_destination;
    sp->cinfo.c.dest = &sp->dest;
    sp->cinfo.c.data_precision = td->td_bitspersample;
    sp->cinfo.c.write_JFIF_header = /* Don't write extraneous markers */
    sp->cinfo.c.write_Adobe_marker = FALSE;
    sp->cinfo.c.image_width = segment_width;
    sp->cinfo.c.image_height = segment_height;
    sp->cinfo.c.comp_info[0].h_samp_factor =
    sp->cinfo.c.comp_info[0].v_samp_factor = 1;
    return CALLVJPEG(sp,jpeg_start_compress(&sp->cinfo.c,FALSE));
#   undef td
  }

static int
OJPEGPreEncode(register TIFF *tif,tsample_t s)
  { register OJPEGState *sp = OJState(tif);
#   define td (&tif->tif_dir)

 /* If we are about to write the first row of an image plane, which should
    coincide with a JPEG "scan", reset the JPEG Library's compressor.  Otherwise
    let the compressor run "as is" and return a "success" status without further
    ado.
 */
    if (     (isTiled(tif) ? tif->tif_curtile : tif->tif_curstrip)
           % td->td_stripsperimage
        == 0
       )

⌨️ 快捷键说明

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