readpng.c 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. /* readpng.c
  2. *
  3. * Copyright (c) 2013 John Cunningham Bowler
  4. *
  5. * This code is released under the libpng license.
  6. * For conditions of distribution and use, see the disclaimer
  7. * and license in png.h
  8. *
  9. * Load an arbitrary number of PNG files (from the command line, or, if there
  10. * are no arguments on the command line, from stdin) then run a time test by
  11. * reading each file by row. The test does nothing with the read result and
  12. * does no transforms. The only output is a time as a floating point number of
  13. * seconds with 9 decimal digits.
  14. */
  15. #include <stdlib.h>
  16. #include <stdio.h>
  17. #include <string.h>
  18. #if defined(HAVE_CONFIG_H) && !defined(PNG_NO_CONFIG_H)
  19. # include <config.h>
  20. #endif
  21. /* Define the following to use this test against your installed libpng, rather
  22. * than the one being built here:
  23. */
  24. #ifdef PNG_FREESTANDING_TESTS
  25. # include <png.h>
  26. #else
  27. # include "../../png.h"
  28. #endif
  29. static int
  30. read_png(FILE *fp)
  31. {
  32. png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,0,0,0);
  33. png_infop info_ptr = NULL;
  34. png_bytep row = NULL, display = NULL;
  35. if (png_ptr == NULL)
  36. return 0;
  37. if (setjmp(png_jmpbuf(png_ptr)))
  38. {
  39. png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
  40. if (row != NULL) free(row);
  41. if (display != NULL) free(display);
  42. return 0;
  43. }
  44. png_init_io(png_ptr, fp);
  45. info_ptr = png_create_info_struct(png_ptr);
  46. if (info_ptr == NULL)
  47. png_error(png_ptr, "OOM allocating info structure");
  48. png_set_keep_unknown_chunks(png_ptr, PNG_HANDLE_CHUNK_ALWAYS, NULL, 0);
  49. png_read_info(png_ptr, info_ptr);
  50. {
  51. size_t rowbytes = png_get_rowbytes(png_ptr, info_ptr);
  52. /* Failure to initialize these is harmless */
  53. row = malloc(rowbytes);
  54. display = malloc(rowbytes);
  55. if (row == NULL || display == NULL)
  56. png_error(png_ptr, "OOM allocating row buffers");
  57. {
  58. png_uint_32 height = png_get_image_height(png_ptr, info_ptr);
  59. # ifdef PNG_READ_INTERLACING_SUPPORTED
  60. int passes = png_set_interlace_handling(png_ptr);
  61. # else /* !READ_INTERLACING */
  62. int passes = png_get_interlace_type(png_ptr, info_ptr) ==
  63. PNG_INTERLACE_ADAM7 ? PNG_INTERLACE_ADAM7_PASSES : 1;
  64. # endif /* !READ_INTERLACING */
  65. int pass;
  66. png_start_read_image(png_ptr);
  67. for (pass = 0; pass < passes; ++pass)
  68. {
  69. png_uint_32 y = height;
  70. # ifndef PNG_READ_INTERLACING_SUPPORTED
  71. if (passes == PNG_INTERLACE_ADAM7_PASSES)
  72. y = PNG_PASS_ROWS(y, pass);
  73. # endif /* READ_INTERLACING */
  74. /* NOTE: this trashes the row each time; interlace handling won't
  75. * work, but this avoids memory thrashing for speed testing.
  76. */
  77. while (y-- > 0)
  78. png_read_row(png_ptr, row, display);
  79. }
  80. }
  81. }
  82. /* Make sure to read to the end of the file: */
  83. png_read_end(png_ptr, info_ptr);
  84. png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
  85. free(row);
  86. free(display);
  87. return 1;
  88. }
  89. int
  90. main(void)
  91. {
  92. /* Exit code 0 on success. */
  93. return !read_png(stdin);
  94. }