FreeCalypso > hg > freecalypso-hwlab
comparison lunalcd/ppmtocmd.c @ 66:09d26f19a2c2
lunalcd: ppmtocmd program written
| author | Mychaela Falconia <falcon@freecalypso.org> | 
|---|---|
| date | Thu, 19 Mar 2020 01:38:57 +0000 | 
| parents | |
| children | 
   comparison
  equal
  deleted
  inserted
  replaced
| 65:cdf2c99e5025 | 66:09d26f19a2c2 | 
|---|---|
| 1 #include <stdio.h> | |
| 2 #include <ctype.h> | |
| 3 #include <stdlib.h> | |
| 4 | |
| 5 static char *ppm_filename; | |
| 6 static FILE *ppmfile; | |
| 7 static int ppm_is_ascii; /* P3 format instead of P6 */ | |
| 8 | |
| 9 /* | |
| 10 * This function reads one ASCII-encoded integer from a PPM file. | |
| 11 * It handles the white space and comment rules of the PPM format. | |
| 12 */ | |
| 13 static int | |
| 14 ppm_get_ascii_number() | |
| 15 { | |
| 16 int accum, c; | |
| 17 | |
| 18 do { | |
| 19 c = getc(ppmfile); | |
| 20 if (c < 0) { | |
| 21 badeof: fprintf(stderr, "%s: unexpected EOF\n", ppm_filename); | |
| 22 return(-1); | |
| 23 } | |
| 24 if (c == '#') { | |
| 25 do | |
| 26 c = getc(ppmfile); | |
| 27 while (c >= 0 && c != '\n'); | |
| 28 if (c != '\n') | |
| 29 goto badeof; | |
| 30 } | |
| 31 } while (isspace(c)); | |
| 32 if (!isdigit(c)) { | |
| 33 fprintf(stderr, | |
| 34 "%s: unexpected data where a number was expected\n", | |
| 35 ppm_filename); | |
| 36 return(-1); | |
| 37 } | |
| 38 for (accum = c - '0'; ; ) { | |
| 39 c = getc(ppmfile); | |
| 40 if (c < 0 || isspace(c)) | |
| 41 break; | |
| 42 if (!isdigit(c)) { | |
| 43 fprintf(stderr, | |
| 44 "%s: bad character in the middle of a number\n", | |
| 45 ppm_filename); | |
| 46 return(-1); | |
| 47 } | |
| 48 accum = accum * 10 + c - '0'; | |
| 49 } | |
| 50 return accum; | |
| 51 } | |
| 52 | |
| 53 /* | |
| 54 * This function reads and parses the PPM header of our input file. | |
| 55 */ | |
| 56 static int | |
| 57 ppm_read_header() | |
| 58 { | |
| 59 int magic1, magic2; | |
| 60 int rd; | |
| 61 | |
| 62 magic1 = getc(ppmfile); | |
| 63 magic2 = getc(ppmfile); | |
| 64 if (magic1 == 'P' && magic2 == '3') | |
| 65 ppm_is_ascii = 1; | |
| 66 else if (magic1 == 'P' && magic2 == '6') | |
| 67 ppm_is_ascii = 0; | |
| 68 else { | |
| 69 fprintf(stderr, "%s: P3 or P6 format expected\n", ppm_filename); | |
| 70 return(-1); | |
| 71 } | |
| 72 rd = ppm_get_ascii_number(); | |
| 73 if (rd < 0) | |
| 74 return(-1); | |
| 75 if (rd != 176) { | |
| 76 fprintf(stderr, "%s: width is not 176\n", ppm_filename); | |
| 77 return(-1); | |
| 78 } | |
| 79 rd = ppm_get_ascii_number(); | |
| 80 if (rd < 0) | |
| 81 return(-1); | |
| 82 if (rd != 220) { | |
| 83 fprintf(stderr, "%s: height is not 220\n", ppm_filename); | |
| 84 return(-1); | |
| 85 } | |
| 86 rd = ppm_get_ascii_number(); | |
| 87 if (rd < 0) | |
| 88 return(-1); | |
| 89 if (rd != 255) { | |
| 90 fprintf(stderr, "%s: maxval is not 255\n", ppm_filename); | |
| 91 return(-1); | |
| 92 } | |
| 93 return(0); | |
| 94 } | |
| 95 | |
| 96 /* | |
| 97 * This function reads a single R, G or B value from a PPM file. | |
| 98 */ | |
| 99 static int | |
| 100 ppm_get_pixval() | |
| 101 { | |
| 102 int c; | |
| 103 | |
| 104 if (ppm_is_ascii) | |
| 105 return ppm_get_ascii_number(); | |
| 106 c = getc(ppmfile); | |
| 107 if (c < 0) { | |
| 108 fprintf(stderr, "%s: EOF while reading binary pixel data\n", | |
| 109 ppm_filename); | |
| 110 return(-1); | |
| 111 } | |
| 112 return c; | |
| 113 } | |
| 114 | |
| 115 static int | |
| 116 ppm_get_rgb() | |
| 117 { | |
| 118 int r, g, b; | |
| 119 | |
| 120 r = ppm_get_pixval(); | |
| 121 if (r < 0) | |
| 122 return(-1); | |
| 123 g = ppm_get_pixval(); | |
| 124 if (g < 0) | |
| 125 return(-1); | |
| 126 b = ppm_get_pixval(); | |
| 127 if (b < 0) | |
| 128 return(-1); | |
| 129 /* convert to 5:6:5 */ | |
| 130 r >>= 3; | |
| 131 g >>= 2; | |
| 132 b >>= 3; | |
| 133 return (r << 11) | (g << 5) | b; | |
| 134 } | |
| 135 | |
| 136 main(argc, argv) | |
| 137 char **argv; | |
| 138 { | |
| 139 int rc; | |
| 140 unsigned n; | |
| 141 | |
| 142 if (argc != 3) { | |
| 143 fprintf(stderr, "usage: %s ppmfile output-mode\n", argv[0]); | |
| 144 exit(1); | |
| 145 } | |
| 146 ppm_filename = argv[1]; | |
| 147 ppmfile = fopen(ppm_filename, "r"); | |
| 148 if (!ppmfile) { | |
| 149 perror(ppm_filename); | |
| 150 exit(1); | |
| 151 } | |
| 152 rc = ppm_read_header(); | |
| 153 if (rc < 0) | |
| 154 exit(1); | |
| 155 set_output_mode(argv[2]); | |
| 156 write_ir(0x20); | |
| 157 write_dr(0); | |
| 158 write_ir(0x21); | |
| 159 write_dr(0); | |
| 160 write_ir(0x22); | |
| 161 bulk_wd_prep(); | |
| 162 for (n = 0; n < 176*220; n++) { | |
| 163 rc = ppm_get_rgb(); | |
| 164 if (rc < 0) | |
| 165 exit(1); | |
| 166 bulk_wd(rc); | |
| 167 } | |
| 168 exit(0); | |
| 169 } | 
