savepng.cc (2136B)
1 /* Copyright 2013 Brian Swetland <swetland@frotz.net> 2 * 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 #include <stdio.h> 17 #include <stdlib.h> 18 #include <string.h> 19 20 #include <png.h> 21 22 #include "util.h" 23 24 int _save_png(const char *fn, png_byte *data, unsigned w, unsigned h, int ch) { 25 png_structp png; 26 png_infop info; 27 FILE *fp; 28 int i, status = -1; 29 30 if ((fp = fopen(fn, "wb")) == NULL) 31 goto exit; 32 33 if (!(png = png_create_write_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0))) 34 goto close_and_exit; 35 36 if (!(info = png_create_info_struct(png))) { 37 png_destroy_write_struct(&png, NULL); 38 goto destroy_and_exit; 39 } 40 41 if (setjmp(png->jmpbuf)) { 42 goto destroy_and_exit; 43 } 44 45 png_init_io(png, fp); 46 47 if (ch == 4) { 48 png_set_IHDR(png, info, w, h, 8, 49 PNG_COLOR_TYPE_RGB_ALPHA, PNG_INTERLACE_NONE, 50 PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); 51 } else if (ch == 1) { 52 png_set_IHDR(png, info, w, h, 8, 53 PNG_COLOR_TYPE_GRAY, PNG_INTERLACE_NONE, 54 PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); 55 } else { 56 png_error(png, "unsupported channel count"); 57 } 58 59 png_write_info(png, info); 60 61 for (i = 0; i < h; i++) 62 png_write_row(png, data + (i * w * ch)); 63 64 png_write_end(png, info); 65 66 status = 0; 67 68 destroy_and_exit: 69 png_destroy_write_struct(&png, &info); 70 71 close_and_exit: 72 fclose(fp); 73 exit: 74 if (status) 75 fprintf(stderr,"failed to save '%s'\n", fn); 76 return status; 77 } 78 79 int save_png_rgba(const char *fn, void *data, unsigned w, unsigned h) { 80 return _save_png(fn, (png_byte*) data, w, h, 4); 81 } 82 83 int save_png_gray(const char *fn, void *data, unsigned w, unsigned h) { 84 return _save_png(fn, (png_byte*) data, w, h, 1); 85 } 86