dumpImage.c 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <unistd.h>
  5. #include "dumpImage.h"
  6. #include <png.h>
  7. #include <setjmp.h>
  8. // data is densely packed
  9. int writePNG(char* path, unsigned int channels, char* data, unsigned int w, unsigned int h) {
  10. FILE* f;
  11. png_byte sig[8];
  12. png_bytep* rowPtrs;
  13. int i;
  14. png_structp pngPtr;
  15. png_infop infoPtr;
  16. int colorTypes[4] = {
  17. PNG_COLOR_TYPE_GRAY,
  18. PNG_COLOR_TYPE_GRAY_ALPHA,
  19. PNG_COLOR_TYPE_RGB,
  20. PNG_COLOR_TYPE_RGB_ALPHA
  21. };
  22. int ret = 2;
  23. // printf("png write | w: %d, h: %d \n", w, h);
  24. if(channels > 4 || channels < 1) {
  25. return 3;
  26. }
  27. // file stuff
  28. f = fopen(path, "wb");
  29. if(!f) {
  30. fprintf(stderr, "Could not open \"%s\" (writePNG).\n", path);
  31. exit(1);
  32. }
  33. /*
  34. if(png_sig_cmp(sig, 0, 8)) {
  35. fprintf(stderr, "\"%s\" is not a valid PNG file.\n", path);
  36. fclose(f);
  37. return NULL;
  38. }
  39. */
  40. // init stuff
  41. pngPtr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
  42. if (!pngPtr) {
  43. goto CLEANUP1;
  44. }
  45. //png_destroy_write_struct (&pngPtr, (png_infopp)NULL);
  46. infoPtr = png_create_info_struct(pngPtr);
  47. if (!infoPtr) {
  48. goto CLEANUP2;
  49. }
  50. //if(infoPtr != NULL) png_free_data(pngPtr, infoPtr, PNG_FREE_ALL, -1);
  51. // header stuff
  52. if (setjmp(png_jmpbuf(pngPtr))) {
  53. goto CLEANUP3;
  54. }
  55. png_init_io(pngPtr, f);
  56. if (setjmp(png_jmpbuf(pngPtr))) {
  57. goto CLEANUP3;
  58. }
  59. png_set_IHDR(pngPtr, infoPtr, w, h,
  60. 8, colorTypes[channels - 1], PNG_INTERLACE_NONE,
  61. PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
  62. png_write_info(pngPtr, infoPtr);
  63. rowPtrs = malloc(h * sizeof(png_bytep));
  64. for(i = 0; i < h; i++) {
  65. rowPtrs[i] = data + (i * w * channels);
  66. }
  67. // write data
  68. if (setjmp(png_jmpbuf(pngPtr))) {
  69. goto CLEANUP4;
  70. }
  71. png_write_image(pngPtr, rowPtrs);
  72. if (setjmp(png_jmpbuf(pngPtr))) {
  73. goto CLEANUP4;
  74. }
  75. png_write_end(pngPtr, NULL);
  76. // success
  77. ret = 0;
  78. CLEANUP4:
  79. free(rowPtrs);
  80. CLEANUP3:
  81. if(infoPtr != NULL) png_free_data(pngPtr, infoPtr, PNG_FREE_ALL, -1);
  82. CLEANUP2:
  83. png_destroy_write_struct (&pngPtr, (png_infopp)NULL);
  84. CLEANUP1:
  85. fclose(f);
  86. return ret;
  87. }