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

📄 pngcrush.c

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

#define NEAR_BUF_SIZE 1024
#define MIN(a,b) (a <= b ? a : b)

void PNGAPI
png_default_write_data(png_structp png_ptr, png_bytep data, png_size_t length)
{
   png_uint_32 check;
   png_byte *near_data;  /* Needs to be "png_byte *" instead of "png_bytep" */
   png_FILE_p io_ptr;

   /* Check if data really is near. If so, use usual code. */
   near_data = (png_byte *)CVT_PTR_NOCHECK(data);
   io_ptr = (png_FILE_p)CVT_PTR(png_ptr->io_ptr);
   if ((png_bytep)near_data == data)
   {
#if defined(_WIN32_WCE)
      if ( !WriteFile(io_ptr, near_data, length, &check, NULL) )
         check = 0;
#else
      check = fwrite(near_data, 1, length, io_ptr);
#endif
   }
   else
   {
      png_byte buf[NEAR_BUF_SIZE];
      png_size_t written, remaining, err;
      check = 0;
      remaining = length;
      do
      {
         written = MIN(NEAR_BUF_SIZE, remaining);
         png_memcpy(buf, data, written); /* copy far buffer to near buffer */
#if defined(_WIN32_WCE)
         if ( !WriteFile(io_ptr, buf, written, &err, NULL) )
            err = 0;
#else
         err = fwrite(buf, 1, written, io_ptr);
#endif
         if (err != written)
            break;
         else
            check += err;
         data += written;
         remaining -= written;
      }
      while (remaining != 0);
   }
   if (check != length)
      png_error(png_ptr, "Write Error");
}

#endif
#endif

#endif /* !defined(PNGCRUSH_H) */



/* cexcept interface */

static void png_cexcept_error(png_structp png_ptr, png_const_charp err_msg)
{
    if (png_ptr);
#if (defined(PNGCRUSH_H))
    if (!strcmp(err_msg, "Too many IDAT's found")) {
#ifndef PNG_NO_CONSOLE_IO
        fprintf(stderr, "\nIn %s, correcting ", inname);
#else
        png_warning(png_ptr, err_msg);
#endif
    } else
#endif /* defined(PNGCRUSH_H) */
    {
        Throw err_msg;
    }
}




/* START of code to validate memory allocation and deallocation */
#ifdef PNG_USER_MEM_SUPPORTED

/*
 * Allocate memory.  For reasonable files, size should never exceed
 * 64K.  However, zlib may allocate more then 64K if you don't tell
 * it not to.  See zconf.h and png.h for more information.  zlib does
 * need to allocate exactly 64K, so whatever you call here must
 * have the ability to do that.
 *
 * This piece of code can be compiled to validate max 64K allocations
 * by setting MAXSEG_64K in zlib zconf.h *or* PNG_MAX_MALLOC_64K.
 */
typedef struct memory_information {
    png_uint_32 size;
    png_voidp pointer;
    struct memory_information FAR *next;
} memory_information;
typedef memory_information FAR *memory_infop;

static memory_infop pinformation = NULL;
static int current_allocation = 0;
static int maximum_allocation = 0;




png_voidp png_debug_malloc(png_structp png_ptr, png_uint_32 size)
{

    /*
     * png_malloc has already tested for NULL; png_create_struct calls
     * png_debug_malloc directly (with png_ptr == NULL prior to libpng-1.2.0
     * which is OK since we are not using a user mem_ptr)
     */

    if (size == 0)
        return (png_voidp) (NULL);

    /*
     * This calls the library allocator twice, once to get the requested
     * buffer and once to get a new free list entry.
     */
    {
        memory_infop pinfo = (memory_infop)png_malloc_default(png_ptr,
           sizeof *pinfo);
        pinfo->size = size;
        current_allocation += size;
        if (current_allocation > maximum_allocation)
            maximum_allocation = current_allocation;
        pinfo->pointer = png_malloc_default(png_ptr, size);
        pinfo->next = pinformation;
        pinformation = pinfo;
        /* Make sure the caller isn't assuming zeroed memory. */
        png_memset(pinfo->pointer, 0xdd, pinfo->size);
        if (verbose > 2)
            fprintf(STDERR, "Pointer %lux allocated %lu bytes\n",
                    (unsigned long) pinfo->pointer, (unsigned long)size);
        return (png_voidp) (pinfo->pointer);
    }
}




/* Free a pointer.  It is removed from the list at the same time. */
void png_debug_free(png_structp png_ptr, png_voidp ptr)
{
    if (png_ptr == NULL)
        fprintf(STDERR, "NULL pointer to png_debug_free.\n");
    if (ptr == 0) {
#if 0 /* This happens all the time. */
        fprintf(STDERR, "WARNING: freeing NULL pointer\n");
#endif
        return;
    }

    /* Unlink the element from the list. */
    {
        memory_infop FAR *ppinfo = &pinformation;
        for (;;) {
            memory_infop pinfo = *ppinfo;
            if (pinfo->pointer == ptr) {
                *ppinfo = pinfo->next;
                current_allocation -= pinfo->size;
                if (current_allocation < 0)
                    fprintf(STDERR, "Duplicate free of memory\n");
                /* We must free the list element too, but first kill
                   the memory that is to be freed. */
                memset(ptr, 0x55, pinfo->size);
                if (verbose > 2)
                    fprintf(STDERR, "Pointer %lux freed %lu bytes\n",
                            (unsigned long) ptr, (unsigned long)pinfo->size);
                png_free_default(png_ptr, pinfo);
                break;
            }
            if (pinfo->next == NULL) {
                fprintf(STDERR, "Pointer %lux not found\n",
                    (unsigned long) ptr);
                break;
            }
            ppinfo = &pinfo->next;
        }
    }

    /* Finally free the data. */
    png_free_default(png_ptr, ptr);
}

#endif /* PNG_USER_MEM_SUPPORTED */
/* END of code to test memory allocation/deallocation */




void png_crush_pause(void)
{
    if (pauses > 0) {
        char keystroke;
        fprintf(STDERR, "Press [ENTER] key to continue.\n");
        keystroke = (char) getc(stdin);
        keystroke = keystroke;  /* stifle compiler warning */
    }
}


void png_skip_chunk(png_structp png_ptr)
{
  png_byte buff[4];
  int i;
  unsigned long length;

  /* read the length field */
  png_default_read_data(png_ptr, buff, 4);
  length=buff[3]+(buff[2]<<8)+(buff[1]<<16)+(buff[0]<<24);
  /* read the chunk name */
  png_default_read_data(png_ptr, buff, 4);
  printf("Skipping %c%c%c%c chunk.\n",buff[0],buff[1],
    buff[2],buff[3]);
  /* skip the data */
  for (i=0; i<length; i++)
     png_default_read_data(png_ptr, buff, 1);
  /* skip the CRC */
  png_default_read_data(png_ptr, buff, 4);
}

#ifndef __riscos
#  define setfiletype(x)

#else /* defined(__riscos) */
#  include <kernel.h>

/* The riscos/acorn support was contributed by Darren Salt. */
static int fileexists(const char *name)
{
# ifdef __acorn
    int ret;
    return _swix(8, 3 | 1 << 31, 17, name, &ret) ? 0 : ret;
# else
    _kernel_swi_regs r;
    r.r[0] = 17;
    r.r[1] = (int) name;
    return _kernel_swi(8, &r, &r) ? 0 : r.r[0];
# endif
}


static int filesize(const char *name)
{
# ifdef __acorn
    int ret;
    return _swix(8, 3 | 1 << 27, 17, name, &ret) ? 0 : ret;
# else
    _kernel_swi_regs r;
    r.r[0] = 17;
    r.r[1] = (int) name;
    return _kernel_swi(8, &r, &r) ? 0 : r.r[4];
# endif
}


static int mkdir(const char *name, int ignored)
{
# ifdef __acorn
    _swi(8, 0x13, 8, name, 0);
    return 0;
# else
    _kernel_swi_regs r;
    r.r[0] = 8;
    r.r[1] = (int) name;
    r.r[4] = r.r[3] = r.r[2] = 0;
    return (int) _kernel_swi(8 | 1 << 31, &r, &r);
# endif
}


static void setfiletype(const char *name)
{
# ifdef __acorn
    _swi(8, 7, 18, name, 0xB60);
# else
    _kernel_swi_regs r;
    r.r[0] = 18;
    r.r[1] = (int) name;
    r.r[2] = 0xB60;
    _kernel_swi(8 | 1 << 31, &r, &r);
# endif
}

#endif /* ?defined(__riscos) */




/*
 * GRR:  basically boolean; first arg is chunk name-string (e.g., "tIME" or
 *       "alla"); second is always full argv[] command line
 *     - remove_chunks is argv index of *last* -rem arg on command line
 *       (would be more efficient to build table at time of cmdline processing!)
 *       (i.e., build removal_list with names or unique IDs or whatever--skip
 *        excessive string-processing on every single one)
 *     - reprocesses command line _every_ time called, looking for -rem opts...
 *     - just like keep_chunk() except that latter sets things_have_changed
 *       variable and debug stmts say "Removed chunk" (but caller actually does
 *       so, by choosing not to copy chunk to new file)
 *     - for any given chunk name, "name" must either match exact command-line
 *       arg (e.g., -rem fOOb), OR it must match one of the official PNG chunk
 *       names explicitly listed below AND command-line arg either used all-
 *       lowercase form or one of "all[ab]" options
 */
int keep_unknown_chunk(png_const_charp name, char *argv[])
{
    int i;
    if (remove_chunks == 0)
        return 1;   /* no -rem options, so always keeping */
    for (i = 1; i <= remove_chunks; i++) {
        if (!strncmp(argv[i], "-rem", 4)) {
            int allb = 0;
            i++;
            if (!strncmp(argv[i], "all", 3)) {
                allb++;  /* all but gamma, but not doing gamma here */
            }
            if (!strncmp(argv[i], name, 4) /* exact chunk-name match in args */
                /* ...or exact match for one of known set, plus args included
                 * either "alla", "allb", or all-lowercase form of "name" */
                || (!strncmp(name, "cHRM", 4)
                    && (!strncmp(argv[i], "chrm", 4) || allb))
                || (!strncmp(name, "dSIG", 4)
                    && (!strncmp(argv[i], "dsig", 4) || allb))
                || (!strncmp(name, "gIFg", 4)
                    && (!strncmp(argv[i], "gifg", 4) || allb))
                || (!strncmp(name, "gIFt", 4)
                    && (!strncmp(argv[i], "gift", 4) || allb))
                || (!strncmp(name, "gIFx", 4)
                    && (!strncmp(argv[i], "gifx", 4) || allb))
                || (!strncmp(name, "hIST", 4)
                    && (!strncmp(argv[i], "hist", 4) || allb))
                || (!strncmp(name, "iCCP", 4)
                    && (!strncmp(argv[i], "iccp", 4) || allb))
                || (!strncmp(name, "pCAL", 4)
                    && (!strncmp(argv[i], "pcal", 4) || allb))
                || (!strncmp(name, "sCAL", 4)
                    && (!strncmp(argv[i], "scal", 4) || allb))
                || (!strncmp(name, "sPLT", 4)
                    && (!strncmp(argv[i], "splt", 4) || allb))
                || (!strncmp(name, "tIME", 4)
                    && (!strncmp(argv[i], "time", 4) || allb)))
            {
                return 0;
            }
        }
    }
    return 1;
}




int keep_chunk(png_const_charp name, char *argv[])
{
    int i;
    if (verbose > 2 && first_trial)
        fprintf(STDERR, "   Read the %s chunk.\n", name);
    if (remove_chunks == 0)
        return 1;
    if (verbose > 1 && first_trial)
        fprintf(STDERR, "     Check for removal of the %s chunk.\n", name);
    for (i = 1; i <= remove_chunks; i++) {
        if (!strncmp(argv[i], "-rem", 4)) {
            int alla = 0;
            int allb = 0;
            int allt = 0;
            i++;
            if (!strncmp(argv[i], "all", 3)) {
                allt++;         /* all forms of text chunk are ancillary */
                allb++;         /* all ancillaries but gamma... */
                if (!strncmp(argv[i], "alla", 4))
                    alla++;     /* ...no, all ancillaries, period */
            } else if (!strncmp(argv[i], "text", 4))
                allt++;         /* all forms of text chunk */
            if (!strncmp(argv[i], name, 4)  /* exact chunk-name match in args
                * ...or exact match for one of known set, plus args included
                * either "alla", "allb", or all-lowercase form of "name": */
                || (!strncmp(name, "PLTE", 4)
   

⌨️ 快捷键说明

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