00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #include <stdio.h>
00028 #include <stdlib.h>
00029 #include <string.h>
00030 #include "ImageIO.h"
00031 #include "Inform.h"
00032
00033 #if defined(VMDPNG)
00034 #include "png.h"
00035 #endif
00036
00037 static void putbyte(FILE * outf, unsigned char val) {
00038 unsigned char buf[1];
00039 buf[0] = val;
00040 fwrite(buf, 1, 1, outf);
00041 }
00042
00043 static void putshort(FILE * outf, unsigned short val) {
00044 unsigned char buf[2];
00045 buf[0] = val >> 8;
00046 buf[1] = val & 0xff;
00047 fwrite(buf, 2, 1, outf);
00048 }
00049
00050 static void putint(FILE * outf, unsigned int val) {
00051 unsigned char buf[4];
00052 buf[0] = (unsigned char) (val >> 24);
00053 buf[1] = (unsigned char) (val >> 16);
00054 buf[2] = (unsigned char) (val >> 8);
00055 buf[3] = (unsigned char) (val & 0xff);
00056 fwrite(buf, 4, 1, outf);
00057 }
00058
00059 void vmd_writergb(FILE *dfile, unsigned char * img, int xs, int ys) {
00060 char iname[80];
00061 int x, y, i;
00062
00063 if (img == NULL)
00064 return;
00065
00066 putshort(dfile, 474);
00067 putbyte(dfile, 0);
00068 putbyte(dfile, 1);
00069 putshort(dfile, 3);
00070 putshort(dfile, xs);
00071 putshort(dfile, ys);
00072 putshort(dfile, 3);
00073 putint(dfile, 0);
00074 putint(dfile, 255);
00075
00076 for(i=0; i<4; i++)
00077 putbyte(dfile, 0);
00078
00079 strcpy(iname, "VMD Snapshot");
00080 fwrite(iname, 80, 1, dfile);
00081 putint(dfile, 0);
00082 for(i=0; i<404; i++)
00083 putbyte(dfile,0);
00084
00085 for(i=0; i<3; i++)
00086 for(y=0; y<ys; y++)
00087 for(x=0; x<xs; x++)
00088 fwrite(&img[(y*xs + x)*3 + i], 1, 1, dfile);
00089
00090 }
00091
00092 static void write_le_int32(FILE * dfile, int num) {
00093 fputc((num ) & 0xFF, dfile);
00094 fputc((num >> 8 ) & 0xFF, dfile);
00095 fputc((num >> 16) & 0xFF, dfile);
00096 fputc((num >> 24) & 0xFF, dfile);
00097 }
00098
00099 static void write_le_int16(FILE * dfile, int num) {
00100 fputc((num ) & 0xFF, dfile);
00101 fputc((num >> 8 ) & 0xFF, dfile);
00102 }
00103
00104
00105 void vmd_writebmp(FILE *dfile, unsigned char * img, int xs, int ys) {
00106 if (img != NULL) {
00107 int imgdataoffset = 14 + 40;
00108 int rowsz = ((xs * 3) + 3) & -4;
00109 int imgdatasize = rowsz * ys;
00110 int filesize = imgdataoffset + imgdatasize;
00111
00112
00113 fputc('B', dfile);
00114 fputc('M', dfile);
00115 write_le_int32(dfile, filesize);
00116 write_le_int16(dfile, 0);
00117 write_le_int16(dfile, 0);
00118 write_le_int32(dfile, imgdataoffset);
00119
00120
00121 write_le_int32(dfile, 40);
00122 write_le_int32(dfile, xs);
00123 write_le_int32(dfile, ys);
00124 write_le_int16(dfile, 1);
00125 write_le_int16(dfile, 24);
00126
00127
00128 write_le_int32(dfile, 0);
00129 write_le_int32(dfile, imgdatasize);
00130 #if 1
00131
00132
00133 write_le_int32(dfile, 11811);
00134 write_le_int32(dfile, 11811);
00135 write_le_int32(dfile, 0);
00136 write_le_int32(dfile, 0);
00137 #else
00138 write_le_int32(dfile, 1000);
00139 write_le_int32(dfile, 1000);
00140 write_le_int32(dfile, 1 << 24);
00141 write_le_int32(dfile, 0);
00142 #endif
00143
00144
00145 int i, y;
00146 unsigned char * rowbuf = (unsigned char *) malloc(rowsz);
00147 if (rowbuf != NULL) {
00148 memset(rowbuf, 0, rowsz);
00149
00150 for (y=0; y<ys; y++) {
00151 int addr = xs * 3 * y;
00152
00153
00154
00155 for (i=0; i<rowsz; i+=3) {
00156 rowbuf[i ] = img[addr + i + 2];
00157 rowbuf[i + 1] = img[addr + i + 1];
00158 rowbuf[i + 2] = img[addr + i ];
00159 }
00160
00161 fwrite(rowbuf, rowsz, 1, dfile);
00162 }
00163 free(rowbuf);
00164 } else {
00165 msgErr << "Failed to save snapshot image!" << sendmsg;
00166 }
00167
00168 }
00169 }
00170
00171
00172 void vmd_writeppm(FILE *dfile, unsigned char * img, int xs, int ys) {
00173 if (img != NULL) {
00174 int y;
00175
00176 fprintf(dfile,"%s\n","P6");
00177 fprintf(dfile,"%d\n", xs);
00178 fprintf(dfile,"%d\n", ys);
00179 fprintf(dfile,"%d\n",255);
00180
00181 for (y=(ys - 1); y>=0; y--) {
00182 fwrite(&img[xs * 3 * y], 1, (xs * 3), dfile);
00183 }
00184 }
00185 }
00186
00187
00188 void vmd_writetga(FILE *dfile, unsigned char * img, int xs, int ys) {
00189 int x, y;
00190
00191 unsigned char * bufpos;
00192 int filepos, numbytes;
00193 unsigned char * fixbuf;
00194
00195 fputc(0, dfile);
00196 fputc(0, dfile);
00197 fputc(2, dfile);
00198 fputc(0, dfile);
00199 fputc(0, dfile);
00200 fputc(0, dfile);
00201 fputc(0, dfile);
00202 fputc(0, dfile);
00203 fputc(0, dfile);
00204 fputc(0, dfile);
00205 fputc(0, dfile);
00206 fputc(0, dfile);
00207 fputc((xs & 0xff), dfile);
00208 fputc(((xs >> 8) & 0xff), dfile);
00209 fputc((ys & 0xff), dfile);
00210 fputc(((ys >> 8) & 0xff), dfile);
00211 fputc(24, dfile);
00212 fputc(0x20, dfile);
00213
00214 fixbuf = (unsigned char *) malloc(xs * 3);
00215 if (fixbuf == NULL) {
00216 msgErr << "vmd_writetga: failed memory allocation!" << sendmsg;
00217 return;
00218 }
00219
00220 for (y=0; y<ys; y++) {
00221 bufpos=img + (xs*3)*(ys-y-1);
00222 filepos=18 + xs*3*y;
00223
00224 if (filepos >= 18) {
00225 fseek(dfile, filepos, 0);
00226
00227 for (x=0; x<(3*xs); x+=3) {
00228 fixbuf[x ] = bufpos[x + 2];
00229 fixbuf[x + 1] = bufpos[x + 1];
00230 fixbuf[x + 2] = bufpos[x ];
00231 }
00232
00233 numbytes = fwrite(fixbuf, 3, xs, dfile);
00234
00235 if (numbytes != xs) {
00236 msgErr << "vmd_writetga: file write problem, "
00237 << numbytes << " bytes written." << sendmsg;
00238 }
00239 }
00240 else {
00241 msgErr << "vmd_writetga: file ptr out of range!!!" << sendmsg;
00242 return;
00243 }
00244 }
00245
00246 free(fixbuf);
00247 }
00248
00249 #if defined(VMDPNG)
00250 void vmd_writepng(FILE *dfile, unsigned char * img, int xs, int ys) {
00251 png_structp png_ptr;
00252 png_infop info_ptr;
00253 png_bytep *row_pointers;
00254 png_textp text_ptr;
00255 int y;
00256
00257
00258 png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
00259 if (png_ptr == NULL) {
00260 msgErr << "Failed to write PNG file" << sendmsg;
00261 return;
00262 }
00263
00264
00265 info_ptr = png_create_info_struct(png_ptr);
00266 if (info_ptr == NULL) {
00267 png_destroy_write_struct(&png_ptr, (png_infopp)NULL);
00268 msgErr << "Failed to write PNG file" << sendmsg;
00269 return;
00270 }
00271
00272
00273 if (setjmp(png_jmpbuf(png_ptr))) {
00274
00275 png_destroy_write_struct(&png_ptr, (png_infopp)NULL);
00276
00277 msgErr << "Failed to write PNG file" << sendmsg;
00278 return;
00279 }
00280
00281
00282 png_init_io(png_ptr, dfile);
00283
00284 png_set_IHDR(png_ptr, info_ptr, xs, ys,
00285 8, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE,
00286 PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
00287
00288 png_set_gAMA(png_ptr, info_ptr, 1.0);
00289
00290 text_ptr = (png_textp) png_malloc(png_ptr, (png_uint_32)sizeof(png_text) * 2);
00291
00292 text_ptr[0].key = "Description";
00293 text_ptr[0].text = "A molecular scene rendered by VMD";
00294 text_ptr[0].compression = PNG_TEXT_COMPRESSION_NONE;
00295 #ifdef PNG_iTXt_SUPPORTED
00296 text_ptr[0].lang = NULL;
00297 #endif
00298
00299 text_ptr[1].key = "Software";
00300 text_ptr[1].text = "VMD -- Visual Molecular Dynamics";
00301 text_ptr[1].compression = PNG_TEXT_COMPRESSION_NONE;
00302 #ifdef PNG_iTXt_SUPPORTED
00303 text_ptr[1].lang = NULL;
00304 #endif
00305 png_set_text(png_ptr, info_ptr, text_ptr, 1);
00306
00307 row_pointers = (png_bytep *) png_malloc(png_ptr, ys*sizeof(png_bytep));
00308 for (y=0; y<ys; y++) {
00309 row_pointers[ys - y - 1] = &img[y * xs * 3];
00310 }
00311
00312 png_set_rows(png_ptr, info_ptr, row_pointers);
00313
00314
00315 png_write_png(png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY, NULL);
00316
00317 png_free(png_ptr, row_pointers);
00318 png_free(png_ptr, text_ptr);
00319
00320
00321 png_destroy_write_struct(&png_ptr, (png_infopp)NULL);
00322
00323 return;
00324 }
00325 #endif