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

📄 tif_ojpeg.c

📁 一个国人自己实现图像库的程序(有参考价值)
💻 C
📖 第 1 页 / 共 5 页
字号:
            TIFFError(module,"JPEG tile height must be multiple of %d",              sp->v_sampling*DCTSIZE);            return 0;          };        if (td->td_tilewidth % (sp->h_sampling*DCTSIZE))          {            TIFFError(module,"JPEG tile width must be multiple of %d",              sp->h_sampling*DCTSIZE);            return 0;          }      }    else      if (   td->td_rowsperstrip < td->td_imagelength          && (td->td_rowsperstrip % (sp->v_sampling*DCTSIZE))         )        {          TIFFError(module,"RowsPerStrip must be multiple of %d for JPEG",            sp->v_sampling*DCTSIZE);          return 0;        };    if (sp->jpegtablesmode & (JPEGTABLESMODE_QUANT|JPEGTABLESMODE_HUFF))      { /* create a JPEGTables field */        if (!prepare_JPEGTables(tif)) return 0;     /* Mark the field "present".  We can't use "TIFFSetField()" because        "BEENWRITING" is already set!     */        TIFFSetFieldBit(tif,FIELD_JPEGTABLES);        tif->tif_flags |= TIFF_DIRTYDIRECT;      }    else   /* We do not support application-supplied JPEG tables, so mark the field      "not present".   */      TIFFClrFieldBit(tif,FIELD_JPEGTABLES);    TIFFojpeg_data_dest(sp,tif); /* send JPEG output to TIFF Library's buffer */    return 1;#   undef td  }/*ARGSUSED*/ static intOJPEGEncode(register TIFF *tif,tidata_t buf,tsize_t cc,tsample_t s)  { 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);    cc /= sp->bytesperline;    while (--cc >= 0)      { JSAMPROW bufptr = (JSAMPROW)buf;        if (TIFFojpeg_write_scanlines(sp,&bufptr,1) != 1) return 0;        ++tif->tif_row;        buf += sp->bytesperline;      };    return 1;  }/*ARGSUSED*/ static intOJPEGEncodeRaw(register TIFF *tif,tidata_t buf,tsize_t cc,tsample_t s)  { 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    multiples. */    if (cc % sp->bytesperline) TIFFWarning(tif->tif_name,no_write_frac);    cc /= sp->bytesperline;    while (--cc >= 0)      {        if (sp->cinfo.c.num_components > 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)                              ( compptr->width_in_blocks * DCTSIZE                              - clumps_per_line * compptr->h_samp_factor                              );                    if (compptr->h_samp_factor == 1) /* Cb & Cr fast path */                      do                        {                          *outptr++ = inptr[0];                          inptr += sp->samplesperclump;                        }                      while (--clumps_per_line > 0);                    else /* general case */                      do                        {                          xpos = 0;                          do *outptr++ = inptr[xpos];                          while (++xpos < compptr->h_samp_factor);                          inptr += sp->samplesperclump;                        }                      while (--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 >= DCTSIZE)          { int n = sp->cinfo.c.max_v_samp_factor*DCTSIZE;            if (TIFFojpeg_write_raw_data(sp,sp->ds_buffer,n) != n) return 0;            sp->scancount = 0;          };        ++tif->tif_row++        buf += sp->bytesperline;      };    return 1;  }static intOJPEGPreEncode(register TIFF *tif,tsample_t s)  { static const char module[]={"OJPEGPreEncode"};    uint32 segment_width, segment_height;    int downsampled_input = FALSE;    register OJPEGState *sp = OJState(tif);#   define td (&tif->tif_dir) /* Set encoding state at the start of a strip or tile. */    if (td->td_planarconfig == PLANARCONFIG_CONTIG)      {        sp->cinfo.c.input_components = td->td_samplesperpixel;        if (sp->photometric == PHOTOMETRIC_YCBCR)          {            if (sp->jpegcolormode == JPEGCOLORMODE_RGB)              sp->cinfo.c.in_color_space = JCS_RGB;            else              {                sp->cinfo.c.in_color_space = JCS_YCbCr;                if (sp->h_sampling != 1 || sp->v_sampling != 1)                  downsampled_input = TRUE;              };            if (!TIFFojpeg_set_colorspace(sp,JCS_YCbCr)) return 0;         /* Set Y sampling factors; we assume "jpeg_set_colorspace()" set the            rest to 1.         */            sp->cinfo.c.comp_info[0].h_samp_factor = sp->h_sampling;            sp->cinfo.c.comp_info[0].v_samp_factor = sp->v_sampling;          }        else          {            sp->cinfo.c.in_color_space = JCS_UNKNOWN;            if (!TIFFojpeg_set_colorspace(sp,JCS_UNKNOWN)) return 0;         /* "jpeg_set_colorspace()" set all sampling factors to 1. */          }      }    else      {        sp->cinfo.c.input_components = 1;        sp->cinfo.c.in_color_space = JCS_UNKNOWN;        if (!TIFFojpeg_set_colorspace(sp,JCS_UNKNOWN)) return 0;        sp->cinfo.c.comp_info[0].component_id = s;     /* "jpeg_set_colorspace()" set all sampling factors to 1. */        if (sp->photometric == PHOTOMETRIC_YCBCR && s > 0)          sp->cinfo.c.comp_info[0].quant_tbl_no =          sp->cinfo.c.comp_info[0].dc_tbl_no =          sp->cinfo.c.comp_info[0].ac_tbl_no = 1;      };    if (isTiled(tif))      {        segment_width = td->td_tilewidth;        segment_height = td->td_tilelength;        sp->bytesperline = TIFFTileRowSize(tif);      }    else      {        segment_width = td->td_imagewidth;        segment_height = td->td_imagelength - tif->tif_row;        if (segment_height > td->td_rowsperstrip)          segment_height = td->td_rowsperstrip;        sp->bytesperline = TIFFScanlineSize(tif);      };    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);      };    if (segment_width > 65535 || segment_height > 65535)      {        TIFFError(module,"Strip/tile too large for JPEG");        return 0;      };    sp->cinfo.c.image_width = segment_width;    sp->cinfo.c.image_height = segment_height;    sp->cinfo.c.write_JFIF_header = /* Don't write extraneous markers */    sp->cinfo.c.write_Adobe_marker = FALSE;    if (!(sp->jpegtablesmode & JPEGTABLESMODE_QUANT)) /* setup table handling */      {        if (!TIFFojpeg_set_quality(sp,sp->jpegquality,FALSE)) return 0;        unsuppress_quant_table(sp,0);        unsuppress_quant_table(sp,1);      };    sp->cinfo.c.optimize_coding = !(sp->jpegtablesmode & JPEGTABLESMODE_HUFF);    tif->tif_encoderow = tif->tif_encodestrip = tif->tif_encodetile =      (sp->cinfo.c.raw_data_in = downsampled_input)      ? OJPEGEncodeRaw : OJPEGEncode;    if (   !TIFFojpeg_start_compress(sp,FALSE) /* start JPEG compressor */        ||     downsampled_input /* allocate downsampled-data buffers */           && !alloc_downsampled_buffers(tif,sp->cinfo.c.comp_info,                                         sp->cinfo.c.num_components)       ) return 0;    sp->scancount = 0;    return 1;#   undef td  }static intOJPEGPostEncode(register TIFF *tif)  { register OJPEGState *sp = OJState(tif); /* Finish up at the end of a strip or tile. */    if (sp->scancount > 0) /* emit partial buffer of down-sampled data */      {        if (sp->scancount < DCTSIZE && sp->cinfo.c.num_components > 0)          { int ci = 0, n;                         /* Pad the data vertically */            register jpeg_component_info *compptr = sp->cinfo.c.comp_info;            do               { tsize_t row_width =                   compptr->width_in_blocks*DCTSIZE*sizeof(JSAMPLE);                 int ypos = sp->scancount*compptr->v_samp_factor;                 do _TIFFmemcpy( (tdata_t)sp->ds_buffer[ci][ypos]                               , (tdata_t)sp->ds_buffer[ci][ypos-1]                               , row_width                               );                 while (++ypos < compptr->v_samp_factor*DCTSIZE);               }            while (++compptr,++ci < sp->cinfo.c.num_components);          };        n = sp->cinfo.c.max_v_samp_factor*DCTSIZE;        if (TIFFojpeg_write_raw_data(sp,sp->ds_buffer,n) != n) return 0;      };    return TIFFojpeg_finish_compress(sp);  }#endif /* never *//* JPEG Decoding begins here. */static intOJPEGSetupDecode(register TIFF *tif)  { static const char module[]={"OJPEGSetupDecode"};    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 != BITS_IN_JSAMPLE)      {        TIFFError(module,bad_bps,td->td_bitspersample);        return 0;      }; /* Almost all old JPEG-in-TIFF encapsulations use 8 bits per sample, but the    following is just a "sanity check", since "OJPEGPreDecode()" actually    depends upon this assumption in certain cases. */    if (td->td_bitspersample != 8)      {        TIFFError(module,"Cannot decompress %u bits per sample");        return 0;      }; /* Grab parameters that are same for all strips/tiles. */    if ((sp->photometric = td->td_photometric) == PHOTOMETRIC_YCBCR)      {        sp->h_sampling = td->td_ycbcrsubsampling[0];        sp->v_sampling = td->td_ycbcrsubsampling[1];      }    else /* TIFF 6.0 forbids subsampling of all other color spaces */      sp->h_sampling = sp->v_sampling = 1;    sp->cinfo.d.src = &sp->src;    sp->src.init_source = std_init_source;    sp->src.fill_input_buffer = std_fill_input_buffer;    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 intOJPEGDecode(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

⌨️ 快捷键说明

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