Grammer
Grammer

Reputation: 321

Trying to write 16-bit PNG

I'm capturing images from camera, and I have two function for saving 16-bit(!) image one in PNG and one in TIFF formats. Could you please explain why the PNG is a very noisy image? like this:

PNG function:

 bool save_image_png(const char *file_name,const mono16bit& img)
{
    [...]
        /* write header */
        if (setjmp(png_jmpbuf(png_ptr)))
                abort_("[write_png_file] Error during writing header");

        png_set_IHDR(png_ptr, info_ptr, width, height,
                     bit_depth,PNG_COLOR_TYPE_GRAY , PNG_INTERLACE_NONE,
                     PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);

        png_write_info(png_ptr, info_ptr);



        /* write bytes */
        if (setjmp(png_jmpbuf(png_ptr)))
                abort_("[write_png_file] Error during writing bytes");

    row_pointers = (png_bytep*) malloc(sizeof(png_bytep) * height);

        for (y=0; y<height; y++)
            row_pointers[y] = (png_byte*) malloc(png_get_rowbytes(png_ptr,info_ptr));
     for (y = 0; y < height; y++)
     {
             row_pointers[y] = (png_bytep)img.getBuffer() + y * width*2;
     }



        png_write_image(png_ptr, row_pointers);


        /* end write */

  [...]           

}

and TIFF function:

 bool save_image(const char *fname,const mono16bit& img)
{
  [...]

  for(y=0; y<height; y++) {
    if((err=TIFFWriteScanline(tif,(tdata_t)(img.getBuffer()+width*y),y,0))==-1)
      break;
  }

  TIFFClose(tif);

  if(err==-1) {
    fprintf(stderr,"Error writing to %s file\n",fname);
    return false;
  }
  return true;

//#endif //USE_LIBTIFF
}

Thank you!

Upvotes: 1

Views: 1627

Answers (2)

Soonts
Soonts

Reputation: 21946

png_set_swap does nothing. You have to actually flip bytes in each pixel of the image.

If you’re on a PC and have SSSE3 or newer, a good way is _mm_shuffle_epi8 instruction, make a permute vector with _mm_setr_epi8.

If you’re on ARM and have NEON, use vrev16q_u8 instruction instead.

Upvotes: 1

pmoleri
pmoleri

Reputation: 4451

Perhaps you have a byte-order problem. Try adding:

png_set_swap(png_ptr);

before saving the image

Upvotes: 0

Related Questions