00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include <ctype.h>
00018 #include <stdio.h>
00019 #include <stdlib.h>
00020 #include <string.h>
00021 #include <fcntl.h>
00022 #include <sys/types.h>
00023 #include <sys/stat.h>
00024
00025 #include "ppm.h"
00026
00027 #define MAGIC_NUMBER "P6"
00028
00029 static void readToken(FILE *fp, char *token)
00030 {
00031 int comment = 0;
00032 char c;
00033
00034 do {
00035 if (fread(&c, 1, 1, fp) != 1) {
00036 perror("reading token failed");
00037 exit(1);
00038 }
00039 if (c == '\n') {
00040 comment = 0;
00041 } else if (c == '#') {
00042 comment = 1;
00043 }
00044 } while (isspace(c) || comment);
00045
00046 *token++ = c;
00047
00048 do {
00049 if (fread(&c, 1, 1, fp) != 1) {
00050 perror("reading token failed");
00051 exit(1);
00052 }
00053 *token++ = c;
00054 } while (! isspace(c));
00055
00056 *--token = '\0';
00057 }
00058
00059 void ppmRead(char *filename, PPMFile *ppmFile)
00060 {
00061 char token[100], msg[100];
00062 int dataSize;
00063 FILE *fp;
00064
00065 if (! (fp = fopen(filename, "rb"))) {
00066 sprintf(msg, "opening image file \"%s\" failed", filename);
00067 perror(msg);
00068 exit(1);
00069 }
00070
00071
00072 readToken(fp, token);
00073 if (strcmp(MAGIC_NUMBER, token)) {
00074 fprintf(stderr, "invalid magic number: %s\n", token);
00075 exit(1);
00076 }
00077
00078
00079 readToken(fp, token);
00080 if (sscanf(token, "%i", &ppmFile->width) != 1) {
00081 fprintf(stderr, "invalid width: %s\n", token);
00082 exit(1);
00083 }
00084 readToken(fp, token);
00085 if (sscanf(token, "%i", &ppmFile->height) != 1) {
00086 fprintf(stderr, "invalid height: %s\n", token);
00087 exit(1);
00088 }
00089
00090
00091 dataSize = ppmFile->width * ppmFile->height * 3;
00092 if (! (ppmFile->data = (unsigned char *)malloc(dataSize))) {
00093 fprintf(stderr, "not enough memory for image data\n");
00094 exit(1);
00095 }
00096
00097
00098 readToken(fp, token);
00099 if (sscanf(token, "%i", &ppmFile->maxVal) != 1) {
00100 fprintf(stderr, "invalid maximum value: %s\n", token);
00101 exit(1);
00102 }
00103
00104
00105 if (fread(ppmFile->data, dataSize, 1, fp) != 1) {
00106 perror("reading image data failed");
00107 exit(1);
00108 }
00109
00110 fclose(fp);
00111 }
00112
00113 void ppmWrite(char *filename, PPMFile *ppmFile)
00114 {
00115 int i, dataSize, maxVal;
00116 FILE *fp;
00117
00118 if (! (fp = fopen(filename, "wb")) == -1) {
00119 perror("opening image file failed");
00120 exit(1);
00121 }
00122
00123
00124 fprintf(fp, "%s\n", MAGIC_NUMBER);
00125
00126
00127 fprintf(fp, "%i %i\n", ppmFile->width, ppmFile->height);
00128
00129
00130 dataSize = ppmFile->width * ppmFile->height * 3;
00131 maxVal = 0;
00132 for (i = 0; i < dataSize; i++) {
00133 if (ppmFile->data[i] > maxVal) {
00134 maxVal = ppmFile->data[i];
00135 }
00136 }
00137 fprintf(fp, "%i\n", maxVal);
00138
00139
00140 if (fwrite(ppmFile->data, dataSize, 1, fp) != 1) {
00141 fprintf(stderr, "writing image data failed\n");
00142 exit(1);
00143 }
00144
00145 fclose(fp);
00146 }