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

📄 pngrtran.c

📁 It was built with libpng version 1.2.35, and is running with libpng version 1.2.35
💻 C
📖 第 1 页 / 共 5 页
字号:
                     {
                        int j, next_j;

                        if (num_new_palette & 0x01)
                        {
                           j = p->left;
                           next_j = p->right;
                        }
                        else
                        {
                           j = p->right;
                           next_j = p->left;
                        }

                        num_new_palette--;
                        palette[png_ptr->index_to_palette[j]]
                          = palette[num_new_palette];
                        if (!full_dither)
                        {
                           int k;

                           for (k = 0; k < num_palette; k++)
                           {
                              if (png_ptr->dither_index[k] ==
                                 png_ptr->index_to_palette[j])
                                 png_ptr->dither_index[k] =
                                    png_ptr->index_to_palette[next_j];
                              if ((int)png_ptr->dither_index[k] ==
                                 num_new_palette)
                                 png_ptr->dither_index[k] =
                                    png_ptr->index_to_palette[j];
                           }
                        }

                        png_ptr->index_to_palette[png_ptr->palette_to_index
                           [num_new_palette]] = png_ptr->index_to_palette[j];
                        png_ptr->palette_to_index[png_ptr->index_to_palette[j]]
                           = png_ptr->palette_to_index[num_new_palette];

                        png_ptr->index_to_palette[j] = (png_byte)num_new_palette;
                        png_ptr->palette_to_index[num_new_palette] = (png_byte)j;
                     }
                     if (num_new_palette <= maximum_colors)
                        break;
                  }
                  if (num_new_palette <= maximum_colors)
                     break;
               }
            }

            for (i = 0; i < 769; i++)
            {
               if (hash[i] != NULL)
               {
                  png_dsortp p = hash[i];
                  while (p)
                  {
                     t = p->next;
                     png_free(png_ptr, p);
                     p = t;
                  }
               }
               hash[i] = 0;
            }
            max_d += 96;
         }
         png_free(png_ptr, hash);
         png_free(png_ptr, png_ptr->palette_to_index);
         png_free(png_ptr, png_ptr->index_to_palette);
         png_ptr->palette_to_index = NULL;
         png_ptr->index_to_palette = NULL;
      }
      num_palette = maximum_colors;
   }
   if (png_ptr->palette == NULL)
   {
      png_ptr->palette = palette;
   }
   png_ptr->num_palette = (png_uint_16)num_palette;

   if (full_dither)
   {
      int i;
      png_bytep distance;
      int total_bits = PNG_DITHER_RED_BITS + PNG_DITHER_GREEN_BITS +
         PNG_DITHER_BLUE_BITS;
      int num_red = (1 << PNG_DITHER_RED_BITS);
      int num_green = (1 << PNG_DITHER_GREEN_BITS);
      int num_blue = (1 << PNG_DITHER_BLUE_BITS);
      png_size_t num_entries = ((png_size_t)1 << total_bits);
      png_ptr->palette_lookup = (png_bytep )png_malloc(png_ptr,
         (png_uint_32)(num_entries * png_sizeof(png_byte)));
      png_memset(png_ptr->palette_lookup, 0, num_entries *
         png_sizeof(png_byte));

      distance = (png_bytep)png_malloc(png_ptr, (png_uint_32)(num_entries *
         png_sizeof(png_byte)));

      png_memset(distance, 0xff, num_entries * png_sizeof(png_byte));

      for (i = 0; i < num_palette; i++)
      {
         int ir, ig, ib;
         int r = (palette[i].red >> (8 - PNG_DITHER_RED_BITS));
         int g = (palette[i].green >> (8 - PNG_DITHER_GREEN_BITS));
         int b = (palette[i].blue >> (8 - PNG_DITHER_BLUE_BITS));

         for (ir = 0; ir < num_red; ir++)
         {
            /* int dr = abs(ir - r); */
            int dr = ((ir > r) ? ir - r : r - ir);
            int index_r = (ir << (PNG_DITHER_BLUE_BITS + PNG_DITHER_GREEN_BITS));

            for (ig = 0; ig < num_green; ig++)
            {
               /* int dg = abs(ig - g); */
               int dg = ((ig > g) ? ig - g : g - ig);
               int dt = dr + dg;
               int dm = ((dr > dg) ? dr : dg);
               int index_g = index_r | (ig << PNG_DITHER_BLUE_BITS);

               for (ib = 0; ib < num_blue; ib++)
               {
                  int d_index = index_g | ib;
                  /* int db = abs(ib - b); */
                  int db = ((ib > b) ? ib - b : b - ib);
                  int dmax = ((dm > db) ? dm : db);
                  int d = dmax + dt + db;

                  if (d < (int)distance[d_index])
                  {
                     distance[d_index] = (png_byte)d;
                     png_ptr->palette_lookup[d_index] = (png_byte)i;
                  }
               }
            }
         }
      }

      png_free(png_ptr, distance);
   }
}
#endif

#if defined(PNG_READ_GAMMA_SUPPORTED) && defined(PNG_FLOATING_POINT_SUPPORTED)
/* Transform the image from the file_gamma to the screen_gamma.  We
 * only do transformations on images where the file_gamma and screen_gamma
 * are not close reciprocals, otherwise it slows things down slightly, and
 * also needlessly introduces small errors.
 *
 * We will turn off gamma transformation later if no semitransparent entries
 * are present in the tRNS array for palette images.  We can't do it here
 * because we don't necessarily have the tRNS chunk yet.
 */
void PNGAPI
png_set_gamma(png_structp png_ptr, double scrn_gamma, double file_gamma)
{
   png_debug(1, "in png_set_gamma");
   if (png_ptr == NULL) return;
   if ((fabs(scrn_gamma * file_gamma - 1.0) > PNG_GAMMA_THRESHOLD) ||
       (png_ptr->color_type & PNG_COLOR_MASK_ALPHA) ||
       (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE))
     png_ptr->transformations |= PNG_GAMMA;
   png_ptr->gamma = (float)file_gamma;
   png_ptr->screen_gamma = (float)scrn_gamma;
}
#endif

#if defined(PNG_READ_EXPAND_SUPPORTED)
/* Expand paletted images to RGB, expand grayscale images of
 * less than 8-bit depth to 8-bit depth, and expand tRNS chunks
 * to alpha channels.
 */
void PNGAPI
png_set_expand(png_structp png_ptr)
{
   png_debug(1, "in png_set_expand");
   if (png_ptr == NULL) return;
   png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS);
   png_ptr->flags &= ~PNG_FLAG_ROW_INIT;
}

/* GRR 19990627:  the following three functions currently are identical
 *  to png_set_expand().  However, it is entirely reasonable that someone
 *  might wish to expand an indexed image to RGB but *not* expand a single,
 *  fully transparent palette entry to a full alpha channel--perhaps instead
 *  convert tRNS to the grayscale/RGB format (16-bit RGB value), or replace
 *  the transparent color with a particular RGB value, or drop tRNS entirely.
 *  IOW, a future version of the library may make the transformations flag
 *  a bit more fine-grained, with separate bits for each of these three
 *  functions.
 *
 *  More to the point, these functions make it obvious what libpng will be
 *  doing, whereas "expand" can (and does) mean any number of things.
 *
 *  GRP 20060307: In libpng-1.4.0, png_set_gray_1_2_4_to_8() was modified
 *  to expand only the sample depth but not to expand the tRNS to alpha.
 */

/* Expand paletted images to RGB. */
void PNGAPI
png_set_palette_to_rgb(png_structp png_ptr)
{
   png_debug(1, "in png_set_palette_to_rgb");
   if (png_ptr == NULL) return;
   png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS);
   png_ptr->flags &= ~PNG_FLAG_ROW_INIT;
}

#if !defined(PNG_1_0_X)
/* Expand grayscale images of less than 8-bit depth to 8 bits. */
void PNGAPI
png_set_expand_gray_1_2_4_to_8(png_structp png_ptr)
{
   png_debug(1, "in png_set_expand_gray_1_2_4_to_8");
   if (png_ptr == NULL) return;
   png_ptr->transformations |= PNG_EXPAND;
   png_ptr->flags &= ~PNG_FLAG_ROW_INIT;
}
#endif

#if defined(PNG_1_0_X) || defined(PNG_1_2_X)
/* Expand grayscale images of less than 8-bit depth to 8 bits. */
/* Deprecated as of libpng-1.2.9 */
void PNGAPI
png_set_gray_1_2_4_to_8(png_structp png_ptr)
{
   png_debug(1, "in png_set_gray_1_2_4_to_8");
   if (png_ptr == NULL) return;
   png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS);
}
#endif


/* Expand tRNS chunks to alpha channels. */
void PNGAPI
png_set_tRNS_to_alpha(png_structp png_ptr)
{
   png_debug(1, "in png_set_tRNS_to_alpha");
   png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS);
   png_ptr->flags &= ~PNG_FLAG_ROW_INIT;
}
#endif /* defined(PNG_READ_EXPAND_SUPPORTED) */

#if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
void PNGAPI
png_set_gray_to_rgb(png_structp png_ptr)
{
   png_debug(1, "in png_set_gray_to_rgb");
   png_ptr->transformations |= PNG_GRAY_TO_RGB;
   png_ptr->flags &= ~PNG_FLAG_ROW_INIT;
}
#endif

#if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
#if defined(PNG_FLOATING_POINT_SUPPORTED)
/* Convert a RGB image to a grayscale of the same width.  This allows us,
 * for example, to convert a 24 bpp RGB image into an 8 bpp grayscale image.
 */

void PNGAPI
png_set_rgb_to_gray(png_structp png_ptr, int error_action, double red,
   double green)
{
      int red_fixed = (int)((float)red*100000.0 + 0.5);
      int green_fixed = (int)((float)green*100000.0 + 0.5);
      if (png_ptr == NULL) return;
      png_set_rgb_to_gray_fixed(png_ptr, error_action, red_fixed, green_fixed);
}
#endif

void PNGAPI
png_set_rgb_to_gray_fixed(png_structp png_ptr, int error_action,
   png_fixed_point red, png_fixed_point green)
{
   png_debug(1, "in png_set_rgb_to_gray");
   if (png_ptr == NULL) return;
   switch(error_action)
   {
      case 1: png_ptr->transformations |= PNG_RGB_TO_GRAY;
              break;
      case 2: png_ptr->transformations |= PNG_RGB_TO_GRAY_WARN;
              break;
      case 3: png_ptr->transformations |= PNG_RGB_TO_GRAY_ERR;
   }
   if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
#if defined(PNG_READ_EXPAND_SUPPORTED)
      png_ptr->transformations |= PNG_EXPAND;
#else
   {
      png_warning(png_ptr,
        "Cannot do RGB_TO_GRAY without EXPAND_SUPPORTED.");
      png_ptr->transformations &= ~PNG_RGB_TO_GRAY;
   }
#endif
   {
      png_uint_16 red_int, green_int;
      if (red < 0 || green < 0)
      {
         red_int   =  6968; /* .212671 * 32768 + .5 */
         green_int = 23434; /* .715160 * 32768 + .5 */
      }
      else if (red + green < 100000L)
      {
        red_int = (png_uint_16)(((png_uint_32)red*32768L)/100000L);
        green_int = (png_uint_16)(((png_uint_32)green*32768L)/100000L);
      }
      else
      {
         png_warning(png_ptr, "ignoring out of range rgb_to_gray coefficients");
         red_int   =  6968;
         green_int = 23434;
      }
      png_ptr->rgb_to_gray_red_coeff   = red_int;
      png_ptr->rgb_to_gray_green_coeff = green_int;
      png_ptr->rgb_to_gray_blue_coeff  =
         (png_uint_16)(32768 - red_int - green_int);
   }
}
#endif

#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
    defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) || \
    defined(PNG_LEGACY_SUPPORTED)
void PNGAPI
png_set_read_user_transform_fn(png_structp png_ptr, png_user_transform_ptr
   read_user_transform_fn)
{
   png_debug(1, "in png_set_read_user_transform_fn");
   if (png_ptr == NULL) return;
#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
   png_ptr->transformations |= PNG_USER_TRANSFORM;
   png_ptr->read_user_transform_fn = read_user_transform_fn;
#endif
#ifdef PNG_LEGACY_SUPPORTED
   if (read_user_transform_fn)
      png_warning(png_ptr,
        "This version of libpng does not support user transforms");
#endif
}
#endif

/* Initialize everything needed for the read.  This includes modifying
 * the palette.
 */
void /* PRIVATE */
png_init_read_transformations(png_structp png_ptr)
{
   png_debug(1, "in png_init_read_transformations");
#if defined(PNG_USELESS_TESTS_SUPPORTED)
   if (png_ptr != NULL)
#endif
  {
#if defined(PNG_READ_BACKGROUND_SUPPORTED) || defined(PNG_READ_SHIFT_SUPPORTED) \
 || defined(PNG_READ_GAMMA_SUPPORTED)
   int color_type = png_ptr->color_type;
#endif

#if defined(PNG_READ_EXPAND_SUPPORTED) && defined(PNG_READ_BACKGROUND_SUPPORTED)

#if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
   /* Detect gray background and attempt to enable optimization
    * for gray --> RGB case */
   /* Note:  if PNG_BACKGROUND_EXPAND is set and color_type is either RGB or
    * RGB_ALPHA (in which case need_expand is superfluous anyway), the
    * background color might actually be gray yet not be flagged as such.
    * This is not a problem for the current code, which uses

⌨️ 快捷键说明

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