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

📄 pngrutil.c

📁 一套图像处理程序,支持三种图像文件格式,我调试过了,很好用
💻 C
📖 第 1 页 / 共 3 页
字号:
            png_bytep sp, dp;
            int sshift, dshift;
            png_byte v;
            png_uint_32 i;
            int j;

            sp = row + (png_size_t)((row_info->width - 1) >> 3);
            sshift = 7 - (int)((row_info->width + 7) & 7);
            dp = row + (png_size_t)((final_width - 1) >> 3);
            dshift = 7 - (int)((final_width + 7) & 7);
            for (i = row_info->width; i; i--)
            {
               v = (png_byte)((*sp >> sshift) & 0x1);
               for (j = 0; j < png_pass_inc[pass]; j++)
               {
                  *dp &= (png_byte)((0x7f7f >> (7 - dshift)) & 0xff);
                  *dp |= (png_byte)(v << dshift);
                  if (dshift == 7)
                  {
                     dshift = 0;
                     dp--;
                  }
                  else
                     dshift++;
               }
               if (sshift == 7)
               {
                  sshift = 0;
                  sp--;
               }
               else
                  sshift++;
            }
            break;
         }
         case 2:
         {
            png_bytep sp, dp;
            int sshift, dshift;
            png_byte v;
            png_uint_32 i, j;

            sp = row + (png_size_t)((row_info->width - 1) >> 2);
            sshift = (png_size_t)((3 - ((row_info->width + 3) & 3)) << 1);
            dp = row + (png_size_t)((final_width - 1) >> 2);
            dshift = (png_size_t)((3 - ((final_width + 3) & 3)) << 1);
            for (i = row_info->width; i; i--)
            {
               v = (png_byte)((*sp >> sshift) & 0x3);
               for (j = 0; j < png_pass_inc[pass]; j++)
               {
                  *dp &= (png_byte)((0x3f3f >> (6 - dshift)) & 0xff);
                  *dp |= (png_byte)(v << dshift);
                  if (dshift == 6)
                  {
                     dshift = 0;
                     dp--;
                  }
                  else
                     dshift += 2;
               }
               if (sshift == 6)
               {
                  sshift = 0;
                  sp--;
               }
               else
                  sshift += 2;
            }
            break;
         }
         case 4:
         {
            png_bytep sp, dp;
            int sshift, dshift;
            png_byte v;
            png_uint_32 i;
            int j;

            sp = row + (png_size_t)((row_info->width - 1) >> 1);
            sshift = (png_size_t)((1 - ((row_info->width + 1) & 1)) << 2);
            dp = row + (png_size_t)((final_width - 1) >> 1);
            dshift = (png_size_t)((1 - ((final_width + 1) & 1)) << 2);
            for (i = row_info->width; i; i--)
            {
               v = (png_byte)((*sp >> sshift) & 0xf);
               for (j = 0; j < png_pass_inc[pass]; j++)
               {
                  *dp &= (png_byte)((0xf0f >> (4 - dshift)) & 0xff);
                  *dp |= (png_byte)(v << dshift);
                  if (dshift == 4)
                  {
                     dshift = 0;
                     dp--;
                  }
                  else
                     dshift = 4;
               }
               if (sshift == 4)
               {
                  sshift = 0;
                  sp--;
               }
               else
                  sshift = 4;
            }
            break;
         }
         default:
         {
            png_bytep sp, dp;
            png_byte v[8];
            png_uint_32 i;
            int j;
            int pixel_bytes;

            pixel_bytes = (row_info->pixel_depth >> 3);

            sp = row + (png_size_t)((row_info->width - 1) * pixel_bytes);
            dp = row + (png_size_t)((final_width - 1) * pixel_bytes);
            for (i = row_info->width; i; i--)
            {
               png_memcpy(v, sp, pixel_bytes);
               for (j = 0; j < png_pass_inc[pass]; j++)
               {
                  png_memcpy(dp, v, pixel_bytes);
                  dp -= pixel_bytes;
               }
               sp -= pixel_bytes;
            }
            break;
         }
      }
      row_info->width = final_width;
      row_info->rowbytes = ((final_width *
         (png_uint_32)row_info->pixel_depth + 7) >> 3);
   }
}
#endif

void
png_read_filter_row(png_structp png_ptr, png_row_infop row_info, png_bytep row,
   png_bytep prev_row, int filter)
{
   switch (filter)
   {
      case 0:
         break;
      case 1:
      {
         png_uint_32 i;
         int bpp;
         png_bytep rp;
         png_bytep lp;

         bpp = (row_info->pixel_depth + 7) / 8;
         for (i = (png_uint_32)bpp, rp = row + bpp, lp = row;
            i < row_info->rowbytes; i++, rp++, lp++)
         {
            *rp = (png_byte)(((int)(*rp) + (int)(*lp)) & 0xff);
         }
         break;
      }
      case 2:
      {
         png_uint_32 i;
         png_bytep rp;
         png_bytep pp;

         for (i = 0, rp = row, pp = prev_row;
            i < row_info->rowbytes; i++, rp++, pp++)
         {
            *rp = (png_byte)(((int)(*rp) + (int)(*pp)) & 0xff);
         }
         break;
      }
      case 3:
      {
         png_uint_32 i;
         int bpp;
         png_bytep rp;
         png_bytep pp;
         png_bytep lp;

         bpp = (row_info->pixel_depth + 7) / 8;
         for (i = 0, rp = row, pp = prev_row;
            i < (png_uint_32)bpp; i++, rp++, pp++)
         {
            *rp = (png_byte)(((int)(*rp) +
               ((int)(*pp) / 2)) & 0xff);
         }
         for (lp = row; i < row_info->rowbytes; i++, rp++, lp++, pp++)
         {
            *rp = (png_byte)(((int)(*rp) +
               (int)(*pp + *lp) / 2) & 0xff);
         }
         break;
      }
      case 4:
      {
         int bpp;
         png_uint_32 i;
         png_bytep rp;
         png_bytep pp;
         png_bytep lp;
         png_bytep cp;

         bpp = (row_info->pixel_depth + 7) / 8;
         for (i = 0, rp = row, pp = prev_row,
            lp = row - bpp, cp = prev_row - bpp;
            i < row_info->rowbytes; i++, rp++, pp++, lp++, cp++)
         {
            int a, b, c, pa, pb, pc, p;

            b = *pp;
            if (i >= (png_uint_32)bpp)
            {
               c = *cp;
               a = *lp;
            }
            else
            {
               a = c = 0;
            }
            p = a + b - c;
            pa = abs(p - a);
            pb = abs(p - b);
            pc = abs(p - c);

            if (pa <= pb && pa <= pc)
               p = a;
            else if (pb <= pc)
               p = b;
            else
               p = c;

            *rp = (png_byte)(((int)(*rp) + p) & 0xff);
         }
         break;
      }
      default:
         png_error(png_ptr, "Bad adaptive filter type");
         break;
   }
}

void
png_read_finish_row(png_structp png_ptr)
{
   png_ptr->row_number++;
   if (png_ptr->row_number < png_ptr->num_rows)
      return;

   if (png_ptr->interlaced)
   {
      png_ptr->row_number = 0;
      png_memset(png_ptr->prev_row, 0, (png_size_t)png_ptr->rowbytes + 1);
      do
      {
         png_ptr->pass++;
         if (png_ptr->pass >= 7)
            break;
         png_ptr->iwidth = (png_ptr->width +
            png_pass_inc[png_ptr->pass] - 1 -
            png_pass_start[png_ptr->pass]) /
            png_pass_inc[png_ptr->pass];
         png_ptr->irowbytes = ((png_ptr->iwidth *
            png_ptr->pixel_depth + 7) >> 3) + 1;
         if (!(png_ptr->transformations & PNG_INTERLACE))
         {
            png_ptr->num_rows = (png_ptr->height +
               png_pass_yinc[png_ptr->pass] - 1 -
               png_pass_ystart[png_ptr->pass]) /
               png_pass_yinc[png_ptr->pass];
            if (!(png_ptr->num_rows))
               continue;
         }
         if (png_ptr->transformations & PNG_INTERLACE)
            break;
      } while (png_ptr->iwidth == 0);

      if (png_ptr->pass < 7)
         return;
   }

   if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED))
   {
      char extra;
      int ret;

      png_ptr->zstream->next_out = (Byte *)&extra;
      png_ptr->zstream->avail_out = (uInt)1;
      do
      {
         if (!(png_ptr->zstream->avail_in))
         {
            while (!png_ptr->idat_size)
            {
               png_byte buf[4];
               png_uint_32 crc;

               png_read_data(png_ptr, buf, 4);
               crc = png_get_uint_32(buf);
               if (((crc ^ 0xffffffffL) & 0xffffffffL) !=
                  (png_ptr->crc & 0xffffffffL))
                  png_warning(png_ptr, "Bad CRC value");

               png_read_data(png_ptr, buf, 4);
               png_ptr->idat_size = png_get_uint_32(buf);
               png_reset_crc(png_ptr);

               png_crc_read(png_ptr, buf, 4);
               if (png_memcmp(buf, png_IDAT, 4))
                  png_error(png_ptr, "Not enough image data");

            }
            png_ptr->zstream->avail_in = (uInt)png_ptr->zbuf_size;
            png_ptr->zstream->next_in = png_ptr->zbuf;
            if (png_ptr->zbuf_size > png_ptr->idat_size)
               png_ptr->zstream->avail_in = (uInt)png_ptr->idat_size;
            png_crc_read(png_ptr, png_ptr->zbuf, png_ptr->zstream->avail_in);
            png_ptr->idat_size -= png_ptr->zstream->avail_in;
         }
         ret = inflate(png_ptr->zstream, Z_PARTIAL_FLUSH);
         if (ret == Z_STREAM_END)
         {
            if (!(png_ptr->zstream->avail_out) || png_ptr->zstream->avail_in ||
               png_ptr->idat_size)
               png_error(png_ptr, "Extra compressed data");
            png_ptr->mode |= PNG_AT_LAST_IDAT;
            break;
         }
         if (ret != Z_OK)
            png_error(png_ptr, png_ptr->zstream->msg ? png_ptr->zstream->msg :
                      "Decompression Error");

         if (!(png_ptr->zstream->avail_out))
            png_error(png_ptr, "Extra compressed data");

      } while (1);
      png_ptr->zstream->avail_out = 0;
   }

   if (png_ptr->idat_size || png_ptr->zstream->avail_in)
      png_error(png_ptr, "Extra compression data");

   inflateReset(png_ptr->zstream);

   png_ptr->mode |= PNG_AT_LAST_IDAT;
}

void
png_read_start_row(png_structp png_ptr)
{
   int max_pixel_depth;
   png_uint_32 rowbytes;

   png_ptr->zstream->avail_in = 0;
   png_init_read_transformations(png_ptr);
   if (png_ptr->interlaced)
   {
      if (!(png_ptr->transformations & PNG_INTERLACE))
         png_ptr->num_rows = (png_ptr->height + png_pass_yinc[0] - 1 -
            png_pass_ystart[0]) / png_pass_yinc[0];
      else
         png_ptr->num_rows = png_ptr->height;

      png_ptr->iwidth = (png_ptr->width +
         png_pass_inc[png_ptr->pass] - 1 -
         png_pass_start[png_ptr->pass]) /
         png_pass_inc[png_ptr->pass];
      png_ptr->irowbytes = ((png_ptr->iwidth *
         png_ptr->pixel_depth + 7) >> 3) + 1;
   }
   else
   {
      png_ptr->num_rows = png_ptr->height;
      png_ptr->iwidth = png_ptr->width;
      png_ptr->irowbytes = png_ptr->rowbytes + 1;
   }

   max_pixel_depth = png_ptr->pixel_depth;

#if defined(PNG_READ_PACK_SUPPORTED)
   if ((png_ptr->transformations & PNG_PACK) && png_ptr->bit_depth < 8)
      max_pixel_depth = 8;
#endif

#if defined(PNG_READ_EXPAND_SUPPORTED)
   if (png_ptr->transformations & PNG_EXPAND)
   {
      if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
      {
         if (png_ptr->num_trans)
            max_pixel_depth = 32;
         else
            max_pixel_depth = 24;
      }
      else if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY)
      {
         if (max_pixel_depth < 8)
            max_pixel_depth = 8;
         if (png_ptr->num_trans)
            max_pixel_depth *= 2;
      }
      else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB)
      {
         if (png_ptr->num_trans)
         {
            max_pixel_depth *= 4;
            max_pixel_depth /= 3;
         }
      }
   }
#endif

#if defined(PNG_READ_FILLER_SUPPORTED)
   if (png_ptr->transformations & (PNG_FILLER))
   {
      if (max_pixel_depth < 32)
         max_pixel_depth = 32;
   }
#endif

#if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
   if (png_ptr->transformations & PNG_GRAY_TO_RGB)
   {
      if ((png_ptr->num_trans && (png_ptr->transformations & PNG_EXPAND)) ||
         png_ptr->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
      {
         if (max_pixel_depth <= 16)
            max_pixel_depth = 32;
         else if (max_pixel_depth <= 32)
            max_pixel_depth = 64;
      }
      else
      {
         if (max_pixel_depth <= 8)
            max_pixel_depth = 24;
         else if (max_pixel_depth <= 16)
            max_pixel_depth = 48;
      }
   }
#endif

   /* align the width on the next larger 8 pixels.  Mainly used
      for interlacing */
   rowbytes = ((png_ptr->width + 7) & ~((png_uint_32)7));
   /* calculate the maximum bytes needed, adding a byte and a pixel
      for safety sake */
   rowbytes = ((rowbytes * (png_uint_32)max_pixel_depth + 7) >> 3) +
      1 + ((max_pixel_depth + 7) >> 3);
#ifdef PNG_MAX_MALLOC_64K
   if (rowbytes > 65536L)
      png_error(png_ptr, "This image requires a row greater than 64KB");
#endif
   png_ptr->row_buf = (png_bytep )png_large_malloc(png_ptr, rowbytes);

#ifdef PNG_MAX_MALLOC_64K
   if (png_ptr->rowbytes + 1 > 65536L)
      png_error(png_ptr, "This image requires a row greater than 64KB");
#endif
   png_ptr->prev_row = png_large_malloc(png_ptr, png_ptr->rowbytes + 1);

   png_memset(png_ptr->prev_row, 0, (png_size_t)png_ptr->rowbytes + 1);

   png_ptr->flags |= PNG_FLAG_ROW_INIT;
}

⌨️ 快捷键说明

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