gcc -std=c99 -g -o _pngwrite pngwrite.c -lpng12
#include <stdio.h>
#include <png.h>
#include <stdlib.h>

// Для libpng характерны ошибки сегментации при пустых параметрах функций.
// Обязательно следите за аргументами функций.
// См. http://zarb.org/~gc/html/libpng.html (A simple libpng example program)

int main(int argc, char **argv) {
  if (argc < 2) {
    printf("pngwrite [filename.png]\n");
    return -1;
  }
  const char *filename = argv[1];
  FILE *f = fopen(filename, "wb");
  int w = 1000;
  int h = 1000;
  int bpp = 8;

  png_structp hw; // Handle for writing
  png_infop info;
  hw = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
  info = png_create_info_struct(hw);
  
  setjmp(png_jmpbuf(hw));
  png_init_io(hw, f);

  setjmp(png_jmpbuf(hw));
  png_set_IHDR(hw, info,
    w, h, bpp, PNG_COLOR_TYPE_RGBA, PNG_INTERLACE_NONE,
    PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
  png_write_info(hw, info); // write header

  png_bytep *rows;
  rows = (png_bytep*)malloc(sizeof(png_bytep)*h);
  for (int y = 0; y < h; y++)
    rows[y] = (png_byte*)malloc(png_get_rowbytes(hw,info));
  printf("%d\n",png_get_rowbytes(hw,info));

  for (int y = 0; y < h; y++)
    for (int x = 0; x < w; x++) {
      rows[y][x*4+0] = x%256;
      rows[y][x*4+1] = y%256;
      rows[y][x*4+2] = y%256;
      rows[y][x*4+3] = 255;
    }

  setjmp(png_jmpbuf(hw));
  png_write_image(hw, rows); // bytes write

  setjmp(png_jmpbuf(hw));
  png_write_end(hw, NULL); // end write

  for (int y = 0; y < h; y++) free(rows[y]);
  free(rows);

  fclose(f);
  return 0;
}