Main Page Namespace List Class Hierarchy Alphabetical List Compound List File List Namespace Members Compound Members File Members Related Pages

ImageIO.C

Go to the documentation of this file.
00001 /***************************************************************************
00002 *cr 
00003 *cr (C) Copyright 1995-2019 The Board of Trustees of the 
00004 *cr University of Illinois 
00005 *cr All Rights Reserved 
00006 *cr 
00007 ***************************************************************************/
00008 
00009 /***************************************************************************
00010 * RCS INFORMATION:
00011 *
00012 * $RCSfile: ImageIO.C,v $
00013 * $Author: johns $ $Locker: $ $State: Exp $
00014 * $Revision: 1.26 $ $Date: 2022年04月08日 06:11:00 $
00015 *
00016 ***************************************************************************
00017 * DESCRIPTION:
00018 * Write an RGB image to a file. Image routines donated by John Stone,
00019 * derived from Tachyon source code. For now these image file writing
00020 * routines are statically linked into VMD and are not even in an extensible
00021 * list structure. Long-term the renderer interface should abstract from
00022 * most of the details, and use a plugin interface for extensibility.
00023 * For the short-term, this gets the job done.
00024 *
00025 ***************************************************************************/
00026 
00027 #include <stdio.h>
00028 #include <stdlib.h>
00029 #include <string.h>
00030 #include "ImageIO.h"
00031 #include "Inform.h"
00032 #include "utilities.h"
00033 
00034 #if defined(VMDLIBPNG)
00035 #include "png.h" // libpng header file
00036 #endif
00037 
00038 static void putbyte(FILE * outf, unsigned char val) {
00039 unsigned char buf[1];
00040 buf[0] = val; 
00041 fwrite(buf, 1, 1, outf);
00042 }
00043 
00044 static void putshort(FILE * outf, unsigned short val) {
00045 unsigned char buf[2];
00046 buf[0] = val >> 8; 
00047 buf[1] = val & 0xff; 
00048 fwrite(buf, 2, 1, outf);
00049 }
00050 
00051 static void putint(FILE * outf, unsigned int val) {
00052 unsigned char buf[4];
00053 buf[0] = (unsigned char) (val >> 24); 
00054 buf[1] = (unsigned char) (val >> 16); 
00055 buf[2] = (unsigned char) (val >> 8); 
00056 buf[3] = (unsigned char) (val & 0xff); 
00057 fwrite(buf, 4, 1, outf);
00058 }
00059 
00060 
00061 unsigned char * cvt_rgb4u_rgb3u(const unsigned char * rgb4u, int xs, int ys) {
00062 int rowlen3u = xs*3;
00063 int sz = xs * ys * 3;
00064 unsigned char * rgb3u = (unsigned char *) calloc(1, sz);
00065 
00066 int x3u, x4f, y;
00067 for (y=0; y<ys; y++) {
00068 int addr3u = y * xs * 3;
00069 int addr4f = y * xs * 4;
00070 for (x3u=0,x4f=0; x3u<rowlen3u; x3u+=3,x4f+=4) {
00071 rgb3u[addr3u + x3u ] = rgb4u[addr4f + x4f ];
00072 rgb3u[addr3u + x3u + 1] = rgb4u[addr4f + x4f + 1];
00073 rgb3u[addr3u + x3u + 2] = rgb4u[addr4f + x4f + 2];
00074 }
00075 }
00076 
00077 return rgb3u;
00078 }
00079 
00080 
00081 unsigned char * cvt_rgb4f_rgb3u(const float * rgb4f, int xs, int ys) {
00082 int rowlen3u = xs*3;
00083 int sz = xs * ys * 3;
00084 unsigned char * rgb3u = (unsigned char *) calloc(1, sz);
00085 
00086 int x3u, x4f, y;
00087 for (y=0; y<ys; y++) {
00088 int addr3u = y * xs * 3;
00089 int addr4f = y * xs * 4;
00090 for (x3u=0,x4f=0; x3u<rowlen3u; x3u+=3,x4f+=4) {
00091 int tmp;
00092 
00093 tmp = int(rgb4f[addr4f + x4f ] * 255.0f);
00094 rgb3u[addr3u + x3u ] = (tmp < 0) ? 0 : ((tmp > 255) ? 255 : tmp);
00095 
00096 tmp = int(rgb4f[addr4f + x4f + 1] * 255.0f);
00097 rgb3u[addr3u + x3u + 1] = (tmp < 0) ? 0 : ((tmp > 255) ? 255 : tmp);
00098 
00099 tmp = int(rgb4f[addr4f + x4f + 2] * 255.0f);
00100 rgb3u[addr3u + x3u + 2] = (tmp < 0) ? 0 : ((tmp > 255) ? 255 : tmp);
00101 }
00102 }
00103 
00104 return rgb3u;
00105 }
00106 
00107 
00108 unsigned char * cvt_rgba4f_rgba4u(const float * rgba4f, int xs, int ys) {
00109 int rowlen4u = xs*4;
00110 int sz = xs * ys * 4;
00111 unsigned char * rgba4u = (unsigned char *) calloc(1, sz);
00112 
00113 int x4u, x4f, y;
00114 for (y=0; y<ys; y++) {
00115 int addr4 = y * xs * 4;
00116 for (x4u=0,x4f=0; x4u<rowlen4u; x4u+=4,x4f+=4) {
00117 int tmp;
00118 
00119 tmp = int(rgba4f[addr4 + x4f ] * 255.0f);
00120 rgba4u[addr4 + x4u ] = (tmp < 0) ? 0 : ((tmp > 255) ? 255 : tmp);
00121 
00122 tmp = int(rgba4f[addr4 + x4f + 1] * 255.0f);
00123 rgba4u[addr4 + x4u + 1] = (tmp < 0) ? 0 : ((tmp > 255) ? 255 : tmp);
00124 
00125 tmp = int(rgba4f[addr4 + x4f + 2] * 255.0f);
00126 rgba4u[addr4 + x4u + 2] = (tmp < 0) ? 0 : ((tmp > 255) ? 255 : tmp);
00127 
00128 tmp = int(rgba4f[addr4 + x4f + 3] * 255.0f);
00129 rgba4u[addr4 + x4u + 3] = (tmp < 0) ? 0 : ((tmp > 255) ? 255 : tmp);
00130 }
00131 }
00132 
00133 return rgba4u;
00134 }
00135 
00136 
00137 static int checkfileextension(const char *s, const char *extension) {
00138 int sz, extsz;
00139 sz = strlen(s);
00140 extsz = strlen(extension);
00141 
00142 if (extsz > sz) return 0;
00143 
00144 if (!strupncmp(s + (sz - extsz), extension, extsz)) return 1;
00145 
00146 return 0;
00147 }
00148 
00149 
00150 int write_image_file_rgb3u(const char *filename,
00151 const unsigned char *rgb3u, int xs, int ys) {
00152 FILE *outfile=NULL;
00153 if ((outfile = fopen(filename, "wb")) == NULL) {
00154 msgErr << "Could not open file " << filename
00155 << " in current directory for writing!" << sendmsg;
00156 return -1;
00157 }
00158 
00159 // write the image to a file on disk
00160 if (checkfileextension(filename, ".bmp")) {
00161 vmd_writebmp(outfile, rgb3u, xs, ys);
00162 #if defined(VMDLIBPNG)
00163 } else if (checkfileextension(filename, ".png")) {
00164 vmd_writepng(outfile, rgb3u, xs, ys);
00165 #endif
00166 } else if (checkfileextension(filename, ".ppm")) {
00167 vmd_writeppm(outfile, rgb3u, xs, ys);
00168 } else if (checkfileextension(filename, ".rgb")) {
00169 vmd_writergb(outfile, rgb3u, xs, ys);
00170 } else if (checkfileextension(filename, ".tga")) {
00171 vmd_writetga(outfile, rgb3u, xs, ys);
00172 } else {
00173 #if defined(_MSC_VER) || defined(WIN32)
00174 msgErr << "Unrecognized image file extension, writing Windows Bitmap file."
00175 << sendmsg;
00176 vmd_writebmp(outfile, rgb3u, xs, ys);
00177 #else
00178 msgErr << "Unrecognized image file extension, writing Targa file."
00179 << sendmsg;
00180 vmd_writetga(outfile, rgb3u, xs, ys);
00181 #endif
00182 }
00183 
00184 fclose(outfile);
00185 return 0;
00186 }
00187 
00188 
00189 int write_image_file_rgb4u(const char *filename,
00190 const unsigned char *rgb4u, int xs, int ys) {
00191 unsigned char *rgb3u = cvt_rgb4u_rgb3u(rgb4u, xs, ys);
00192 if (rgb3u == NULL)
00193 return -1;
00194 
00195 if (write_image_file_rgb3u(filename, rgb3u, xs, ys)) {
00196 free(rgb3u);
00197 return -1;
00198 }
00199 
00200 free(rgb3u);
00201 return 0;
00202 }
00203 
00204 
00205 int write_image_file_rgb4f(const char *filename,
00206 const float *rgb4f, int xs, int ys) {
00207 unsigned char *rgb3u = cvt_rgb4f_rgb3u(rgb4f, xs, ys);
00208 if (rgb3u == NULL)
00209 return -1;
00210 
00211 if (write_image_file_rgb3u(filename, rgb3u, xs, ys)) {
00212 free(rgb3u);
00213 return -1;
00214 }
00215 
00216 free(rgb3u);
00217 return 0;
00218 }
00219 
00220 
00221 int write_image_file_rgba4u(const char *filename,
00222 const unsigned char *rgba4u, int xs, int ys) {
00223 FILE *outfile=NULL;
00224 if ((outfile = fopen(filename, "wb")) == NULL) {
00225 msgErr << "Could not open file " << filename
00226 << " in current directory for writing!" << sendmsg;
00227 return -1;
00228 }
00229 
00230 if (checkfileextension(filename, ".png")) {
00231 #if defined(VMDLIBPNG)
00232 vmd_writepng_alpha(outfile, rgba4u, xs, ys);
00233 #else
00234 msgErr << "Unrecognized or unsupported alpha-channel image format."
00235 << sendmsg;
00236 
00237 fclose(outfile);
00238 return -1;
00239 #endif
00240 } else {
00241 msgErr << "Unrecognized or unsupported alpha-channel image format."
00242 << sendmsg;
00243 
00244 fclose(outfile);
00245 return -1;
00246 }
00247 
00248 fclose(outfile);
00249 return 0;
00250 }
00251 
00252 
00253 int write_image_file_rgba4f(const char *filename,
00254 const float *rgba4f, int xs, int ys) {
00255 unsigned char *rgba4u = cvt_rgba4f_rgba4u(rgba4f, xs, ys);
00256 if (rgba4u == NULL)
00257 return -1;
00258 
00259 if (write_image_file_rgba4u(filename, rgba4u, xs, ys)) {
00260 free(rgba4u);
00261 return -1;
00262 }
00263 
00264 free(rgba4u);
00265 return 0;
00266 }
00267 
00268 
00269 void vmd_writergb(FILE *dfile, const unsigned char * img, int xs, int ys) {
00270 char iname[80]; /* Image name */
00271 int x, y, i;
00272 
00273 if (img == NULL) 
00274 return;
00275 
00276 putshort(dfile, 474); /* Magic */
00277 putbyte(dfile, 0); /* STORAGE is VERBATIM */
00278 putbyte(dfile, 1); /* BPC is 1 */
00279 putshort(dfile, 3); /* DIMENSION is 3 */
00280 putshort(dfile, xs); /* XSIZE */
00281 putshort(dfile, ys); /* YSIZE */
00282 putshort(dfile, 3); /* ZSIZE */
00283 putint(dfile, 0); /* PIXMIN is 0 */
00284 putint(dfile, 255); /* PIXMAX is 255 */
00285 
00286 for(i=0; i<4; i++) /* DUMMY 4 bytes */
00287 putbyte(dfile, 0);
00288 
00289 strcpy(iname, "VMD Snapshot");
00290 fwrite(iname, 80, 1, dfile); /* IMAGENAME */
00291 putint(dfile, 0); /* COLORMAP is 0 */
00292 for(i=0; i<404; i++) /* DUMMY 404 bytes */
00293 putbyte(dfile,0);
00294 
00295 for(i=0; i<3; i++)
00296 for(y=0; y<ys; y++)
00297 for(x=0; x<xs; x++)
00298 fwrite(&img[(y*xs + x)*3 + i], 1, 1, dfile);
00299 }
00300 
00301 static void write_le_int32(FILE * dfile, int num) {
00302 fputc((num ) & 0xFF, dfile);
00303 fputc((num >> 8 ) & 0xFF, dfile);
00304 fputc((num >> 16) & 0xFF, dfile);
00305 fputc((num >> 24) & 0xFF, dfile);
00306 }
00307 
00308 static void write_le_int16(FILE * dfile, int num) {
00309 fputc((num ) & 0xFF, dfile);
00310 fputc((num >> 8 ) & 0xFF, dfile);
00311 }
00312 
00313 
00314 void vmd_writebmp(FILE *dfile, const unsigned char * img, int xs, int ys) {
00315 if (img != NULL) {
00316 int imgdataoffset = 14 + 40; // file header size + bitmap header size
00317 int rowlen = xs * 3; // non-padded length of row of pixels
00318 int rowsz = ((rowlen) + 3) & -4; // size of one padded row of pixels
00319 int imgdatasize = rowsz * ys; // size of image data
00320 int filesize = imgdataoffset + imgdatasize;
00321 
00322 // write out bitmap file header (14 bytes)
00323 fputc('B', dfile); 
00324 fputc('M', dfile);
00325 write_le_int32(dfile, filesize);
00326 write_le_int16(dfile, 0);
00327 write_le_int16(dfile, 0);
00328 write_le_int32(dfile, imgdataoffset);
00329 
00330 // write out bitmap header (40 bytes)
00331 write_le_int32(dfile, 40); // size of bitmap header structure
00332 write_le_int32(dfile, xs); // size of image in x
00333 write_le_int32(dfile, ys); // size of image in y
00334 write_le_int16(dfile, 1); // number of color planes (only "1" is legal)
00335 write_le_int16(dfile, 24); // bits per pixel
00336 
00337 // fields added in Win 3.x
00338 write_le_int32(dfile, 0); // compression used (0 == none)
00339 write_le_int32(dfile, imgdatasize); // size of bitmap in bytes 
00340 
00341 // imported improvements from the Tachyon BMP writer to address 
00342 // the behavior of BMP files loaded for display on Android devices
00343 write_le_int32(dfile, 11811); // X pixels per meter (300dpi)
00344 write_le_int32(dfile, 11811); // Y pixels per meter (300dpi)
00345 write_le_int32(dfile, 0); // color count (0 for RGB)
00346 write_le_int32(dfile, 0); // important colors (0 for RGB)
00347 
00348 // write out actual image data
00349 int i, y;
00350 unsigned char * rowbuf = (unsigned char *) malloc(rowsz);
00351 if (rowbuf != NULL) { 
00352 memset(rowbuf, 0, rowsz); // clear the buffer (and padding) to black.
00353 
00354 for (y=0; y<ys; y++) {
00355 int addr = xs * 3 * y;
00356 
00357 // write one row of the image, in reversed RGB -> BGR pixel order
00358 // padding bytes should remain 0's, shouldn't have to re-clear them.
00359 for (i=0; i<rowlen; i+=3) {
00360 rowbuf[i ] = img[addr + i + 2]; // blue
00361 rowbuf[i + 1] = img[addr + i + 1]; // green
00362 rowbuf[i + 2] = img[addr + i ]; // red 
00363 }
00364 
00365 fwrite(rowbuf, rowsz, 1, dfile); // write the whole row of pixels 
00366 }
00367 free(rowbuf); 
00368 } else {
00369 msgErr << "Failed to save snapshot image!" << sendmsg;
00370 }
00371 
00372 } // img != NULL
00373 }
00374 
00375 
00376 void vmd_writeppm(FILE *dfile, const unsigned char * img, int xs, int ys) {
00377 if (img != NULL) {
00378 int y;
00379 
00380 fprintf(dfile,"%s\n","P6");
00381 fprintf(dfile,"%d\n", xs);
00382 fprintf(dfile,"%d\n", ys);
00383 fprintf(dfile,"%d\n",255); /* maxval */
00384 
00385 for (y=(ys - 1); y>=0; y--) {
00386 fwrite(&img[xs * 3 * y], 1, (xs * 3), dfile);
00387 }
00388 }
00389 }
00390 
00391 
00392 void vmd_writetga(FILE *dfile, const unsigned char * img, int xs, int ys) {
00393 int x, y;
00394 
00395 const unsigned char * bufpos;
00396 int filepos, numbytes;
00397 unsigned char * fixbuf;
00398 
00399 fputc(0, dfile); /* IdLength */
00400 fputc(0, dfile); /* ColorMapType */
00401 fputc(2, dfile); /* ImageTypeCode */
00402 fputc(0, dfile); /* ColorMapOrigin, low byte */
00403 fputc(0, dfile); /* ColorMapOrigin, high byte */
00404 fputc(0, dfile); /* ColorMapLength, low byte */
00405 fputc(0, dfile); /* ColorMapLength, high byte */
00406 fputc(0, dfile); /* ColorMapEntrySize */
00407 fputc(0, dfile); /* XOrigin, low byte */
00408 fputc(0, dfile); /* XOrigin, high byte */
00409 fputc(0, dfile); /* YOrigin, low byte */
00410 fputc(0, dfile); /* YOrigin, high byte */
00411 fputc((xs & 0xff), dfile); /* Width, low byte */
00412 fputc(((xs >> 8) & 0xff), dfile); /* Width, high byte */
00413 fputc((ys & 0xff), dfile); /* Height, low byte */
00414 fputc(((ys >> 8) & 0xff), dfile); /* Height, high byte */
00415 fputc(24, dfile); /* ImagePixelSize */
00416 fputc(0x20, dfile); /* ImageDescriptorByte 0x20 == flip vertically */
00417 
00418 fixbuf = (unsigned char *) malloc(xs * 3);
00419 if (fixbuf == NULL) {
00420 msgErr << "vmd_writetga: failed memory allocation!" << sendmsg;
00421 return;
00422 }
00423 
00424 for (y=0; y<ys; y++) {
00425 bufpos=img + (xs*3)*(ys-y-1);
00426 filepos=18 + xs*3*y;
00427 
00428 if (filepos >= 18) {
00429 fseek(dfile, filepos, 0);
00430 
00431 for (x=0; x<(3*xs); x+=3) {
00432 fixbuf[x ] = bufpos[x + 2];
00433 fixbuf[x + 1] = bufpos[x + 1];
00434 fixbuf[x + 2] = bufpos[x ];
00435 }
00436 
00437 numbytes = fwrite(fixbuf, 3, xs, dfile);
00438 
00439 if (numbytes != xs) {
00440 msgErr << "vmd_writetga: file write problem, " 
00441 << numbytes << " bytes written." << sendmsg;
00442 }
00443 }
00444 else {
00445 msgErr << "vmd_writetga: file ptr out of range!!!" << sendmsg;
00446 return; /* don't try to continue */
00447 }
00448 }
00449 
00450 free(fixbuf);
00451 }
00452 
00453 #if defined(VMDLIBPNG)
00454 void vmd_writepng(FILE *dfile, const unsigned char * img, int xs, int ys) {
00455 png_structp png_ptr;
00456 png_infop info_ptr;
00457 png_bytep *row_pointers;
00458 png_textp text_ptr;
00459 int y;
00460 
00461 /* Create and initialize the png_struct with the default error handlers */
00462 png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
00463 if (png_ptr == NULL) {
00464 msgErr << "Failed to write PNG file" << sendmsg;
00465 return; /* Could not initialize PNG library, return error */
00466 }
00467 
00468 /* Allocate/initialize the memory for image information. REQUIRED. */
00469 info_ptr = png_create_info_struct(png_ptr);
00470 if (info_ptr == NULL) {
00471 png_destroy_write_struct(&png_ptr, (png_infopp)NULL);
00472 msgErr << "Failed to write PNG file" << sendmsg;
00473 return; /* Could not initialize PNG library, return error */
00474 }
00475 
00476 /* Set error handling for setjmp/longjmp method of libpng error handling */
00477 if (setjmp(png_jmpbuf(png_ptr))) {
00478 /* Free all of the memory associated with the png_ptr and info_ptr */
00479 png_destroy_write_struct(&png_ptr, (png_infopp)NULL);
00480 /* If we get here, we had a problem writing the file */
00481 msgErr << "Failed to write PNG file" << sendmsg;
00482 return; /* Could not open image, return error */
00483 }
00484 
00485 /* Set up the input control if you are using standard C streams */
00486 png_init_io(png_ptr, dfile);
00487 
00488 png_set_IHDR(png_ptr, info_ptr, xs, ys,
00489 8, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE,
00490 PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
00491 
00492 png_set_gAMA(png_ptr, info_ptr, 1.0);
00493 
00494 text_ptr = (png_textp) png_malloc(png_ptr, (png_uint_32)sizeof(png_text) * 2);
00495 
00496 text_ptr[0].key = (char *) "Description";
00497 text_ptr[0].text = (char *) "A molecular scene rendered by VMD";
00498 text_ptr[0].compression = PNG_TEXT_COMPRESSION_NONE;
00499 #ifdef PNG_iTXt_SUPPORTED
00500 text_ptr[0].lang = NULL;
00501 #endif
00502 
00503 text_ptr[1].key = (char *) "Software";
00504 text_ptr[1].text = (char *) "VMD -- Visual Molecular Dynamics";
00505 text_ptr[1].compression = PNG_TEXT_COMPRESSION_NONE;
00506 #ifdef PNG_iTXt_SUPPORTED
00507 text_ptr[1].lang = NULL;
00508 #endif
00509 png_set_text(png_ptr, info_ptr, text_ptr, 1);
00510 
00511 row_pointers = (png_bytep *) png_malloc(png_ptr, ys*sizeof(png_bytep));
00512 for (y=0; y<ys; y++) {
00513 row_pointers[ys - y - 1] = (png_bytep) &img[y * xs * 3];
00514 }
00515 
00516 png_set_rows(png_ptr, info_ptr, row_pointers);
00517 
00518 /* one-shot call to write the whole PNG file into memory */
00519 png_write_png(png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY, NULL);
00520 
00521 png_free(png_ptr, row_pointers);
00522 png_free(png_ptr, text_ptr);
00523 
00524 /* clean up after the write and free any memory allocated - REQUIRED */
00525 png_destroy_write_struct(&png_ptr, (png_infopp)NULL);
00526 
00527 return; /* No fatal errors */
00528 }
00529 
00530 
00531 void vmd_writepng_alpha(FILE *dfile, const unsigned char * img, int xs, int ys) {
00532 png_structp png_ptr;
00533 png_infop info_ptr;
00534 png_bytep *row_pointers;
00535 png_textp text_ptr;
00536 int y;
00537 
00538 /* Create and initialize the png_struct with the default error handlers */
00539 png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
00540 if (png_ptr == NULL) {
00541 msgErr << "Failed to write PNG file" << sendmsg;
00542 return; /* Could not initialize PNG library, return error */
00543 }
00544 
00545 /* Allocate/initialize the memory for image information. REQUIRED. */
00546 info_ptr = png_create_info_struct(png_ptr);
00547 if (info_ptr == NULL) {
00548 png_destroy_write_struct(&png_ptr, (png_infopp)NULL);
00549 msgErr << "Failed to write PNG file" << sendmsg;
00550 return; /* Could not initialize PNG library, return error */
00551 }
00552 
00553 /* Set error handling for setjmp/longjmp method of libpng error handling */
00554 if (setjmp(png_jmpbuf(png_ptr))) {
00555 /* Free all of the memory associated with the png_ptr and info_ptr */
00556 png_destroy_write_struct(&png_ptr, (png_infopp)NULL);
00557 /* If we get here, we had a problem writing the file */
00558 msgErr << "Failed to write PNG file" << sendmsg;
00559 return; /* Could not open image, return error */
00560 }
00561 
00562 /* Set up the input control if you are using standard C streams */
00563 png_init_io(png_ptr, dfile);
00564 
00565 png_set_IHDR(png_ptr, info_ptr, xs, ys,
00566 8, PNG_COLOR_TYPE_RGB_ALPHA, PNG_INTERLACE_NONE,
00567 PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
00568 
00569 // png_set_alpha_mode(png_ptr, PNG_ALPHA_STANDARD, PNG_GAMMA_LINEAR);
00570 
00571 #if 0
00572 /* optional significant bit chunk */
00573 png_color_8 sig_bit;
00574 memset(&sig_bit, 0, sizeof(sig_bit));
00575 
00576 sig_bit.red = 8;
00577 sig_bit.green = 8;
00578 sig_bit.blue = 8;
00579 sig_bit.alpha = 8;
00580 
00581 png_set_sBIT(png_ptr, info_ptr, &sig_bit);
00582 #endif
00583 
00584 png_set_gAMA(png_ptr, info_ptr, 1.0);
00585 
00586 text_ptr = (png_textp) png_malloc(png_ptr, (png_uint_32)sizeof(png_text) * 2);
00587 
00588 text_ptr[0].key = (char *) "Description";
00589 text_ptr[0].text = (char *) "A molecular scene rendered by VMD";
00590 text_ptr[0].compression = PNG_TEXT_COMPRESSION_NONE;
00591 #ifdef PNG_iTXt_SUPPORTED
00592 text_ptr[0].lang = NULL;
00593 #endif
00594 
00595 text_ptr[1].key = (char *) "Software";
00596 text_ptr[1].text = (char *) "VMD -- Visual Molecular Dynamics";
00597 text_ptr[1].compression = PNG_TEXT_COMPRESSION_NONE;
00598 #ifdef PNG_iTXt_SUPPORTED
00599 text_ptr[1].lang = NULL;
00600 #endif
00601 png_set_text(png_ptr, info_ptr, text_ptr, 1);
00602 
00603 // png_write_info(png_ptr, info_ptr);
00604 
00605 row_pointers = (png_bytep *) png_malloc(png_ptr, ys*sizeof(png_bytep));
00606 for (y=0; y<ys; y++) {
00607 row_pointers[ys - y - 1] = (png_bytep) &img[y * xs * 4];
00608 }
00609 
00610 png_set_rows(png_ptr, info_ptr, row_pointers);
00611 
00612 /* one-shot call to write the whole PNG file into memory */
00613 png_write_png(png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY, NULL);
00614 
00615 png_free(png_ptr, row_pointers);
00616 png_free(png_ptr, text_ptr);
00617 
00618 /* clean up after the write and free any memory allocated - REQUIRED */
00619 png_destroy_write_struct(&png_ptr, (png_infopp)NULL);
00620 
00621 return; /* No fatal errors */
00622 }
00623 
00624 #endif

Generated on Wed Nov 19 02:46:23 2025 for VMD (current) by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002

AltStyle によって変換されたページ (->オリジナル) /