fork download
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <assert.h>
  4. #include <math.h>
  5. #include <string.h>
  6.  
  7. /* #define DEBUG */
  8. #if defined(DEBUG)
  9. #include "xmalloc.h"
  10. #else
  11. #define xmalloc(x, y) malloc(x)
  12. #define xfree(x, y) free(x)
  13. #define xrealloc(x, y, z) realloc(x, y)
  14. #define xmallocdump()
  15. #endif
  16. /* for xmalloc.c */
  17. #define IDRGB 1001
  18. #define IDPALETTE 1002
  19. #define IDBMP 1003
  20. #define ID_GETLINE 1004
  21.  
  22. typedef struct {
  23. unsigned char bfType1;
  24. unsigned char bfType2;
  25. unsigned long bfSize;
  26. unsigned short bfReserved1;
  27. unsigned short bfReserved2;
  28. unsigned long bfOffBits;
  29. } BitmapFileHeader;
  30.  
  31. int bmHeaderCheck(FILE *fp, BitmapFileHeader *bh) {
  32. assert(sizeof(unsigned short) == 2);
  33. assert(sizeof(unsigned long) == 4);
  34. if (fread(&(bh->bfType1), sizeof(unsigned char), 1, fp) != 1)
  35. goto error_NotRead;
  36. if (fread(&(bh->bfType2), sizeof(unsigned char), 1, fp) != 1)
  37. goto error_NotRead;
  38. if (fread(&(bh->bfSize), sizeof(unsigned long), 1, fp) != 1)
  39. goto error_NotRead;
  40. if (fread(&(bh->bfReserved1), sizeof(unsigned short), 1, fp) != 1)
  41. goto error_NotRead;
  42. if (fread(&(bh->bfReserved2), sizeof(unsigned short), 1, fp) != 1)
  43. goto error_NotRead;
  44. if (fread(&(bh->bfOffBits), sizeof(unsigned long), 1, fp) != 1)
  45. goto error_NotRead;
  46. if (bh->bfType1 != 'B' || bh->bfType2 != 'M')
  47. goto error_NotBitmap;
  48. if (bh->bfReserved1 != 0 || bh->bfReserved2 != 0)
  49. goto error_NotBitmap;
  50. #if 0
  51. printf("read:bfType1: %c\n", bh->bfType1);
  52. printf("read:bfType2: %c\n", bh->bfType2);
  53. printf("read:bfSize: %lu\n", bh->bfSize);
  54. printf("read:bfReserved1: %u\n", bh->bfReserved1);
  55. printf("read:bfReserved2: %u\n", bh->bfReserved2);
  56. printf("read:bfOffBits: %lu\n", bh->bfOffBits);
  57. putchar('\n');
  58. #endif
  59. return 1;
  60.  
  61. error_NotBitmap:
  62. fprintf(stderr, "cannot find bmp header\n");
  63. return 0;
  64. error_NotRead:
  65. fprintf(stderr, "cannot read bmp header\n");
  66. return 0;
  67. }
  68.  
  69. typedef struct {
  70. unsigned long biSize;
  71. long biWidth;
  72. long biHeight;
  73. unsigned short biPlanes;
  74. unsigned short biBitCount;
  75. unsigned long biCompression;
  76. unsigned long biSizeImage;
  77. long biXPixPerMeter;
  78. long biYPixPerMeter;
  79. unsigned long biClrUsed;
  80. unsigned long biClrImportant;
  81. } BitmapInfoHeader;
  82.  
  83. int bmInfoHeaderCheck(FILE *fp, BitmapInfoHeader *bi) {
  84. assert(sizeof(unsigned short) == 2);
  85. assert(sizeof(unsigned long) == 4);
  86. assert(sizeof(long) == 4);
  87. if (fread(&(bi->biSize), sizeof(unsigned long), 1, fp) != 1)
  88. goto error_NotRead;
  89. if (bi->biSize == 12) {
  90. bi->biWidth = 0;
  91. if (fread(&(bi->biWidth), sizeof(short), 1, fp) != 1)
  92. goto error_NotRead;
  93. bi->biHeight = 0;
  94. if (fread(&(bi->biHeight), sizeof(short), 1, fp) != 1)
  95. goto error_NotRead;
  96. if (fread(&(bi->biPlanes), sizeof(unsigned short), 1, fp) != 1)
  97. goto error_NotRead;
  98. if (fread(&(bi->biBitCount), sizeof(unsigned short), 1, fp) != 1)
  99. goto error_NotRead;
  100. if (bi->biWidth > 32768)
  101. bi->biWidth = -bi->biWidth;
  102. if (bi->biHeight > 32768)
  103. bi->biWidth = -bi->biHeight;
  104. } else if (bi->biSize == 40) {
  105. if (fread(&(bi->biWidth), sizeof(long), 1, fp) != 1)
  106. goto error_NotRead;
  107. if (fread(&(bi->biHeight), sizeof(long), 1, fp) != 1)
  108. goto error_NotRead;
  109. if (fread(&(bi->biPlanes), sizeof(unsigned short), 1, fp) != 1)
  110. goto error_NotRead;
  111. if (fread(&(bi->biBitCount), sizeof(unsigned short), 1, fp) != 1)
  112. goto error_NotRead;
  113. if (fread(&(bi->biCompression), sizeof(unsigned long), 1, fp) != 1)
  114. goto error_NotRead;
  115. if (fread(&(bi->biSizeImage), sizeof(unsigned long), 1, fp) != 1)
  116. goto error_NotRead;
  117. if (fread(&(bi->biXPixPerMeter), sizeof(long), 1, fp) != 1)
  118. goto error_NotRead;
  119. if (fread(&(bi->biYPixPerMeter), sizeof(long), 1, fp) != 1)
  120. goto error_NotRead;
  121. if (fread(&(bi->biClrUsed), sizeof(unsigned long), 1, fp) != 1)
  122. goto error_NotRead;
  123. if (fread(&(bi->biClrImportant), sizeof(unsigned long), 1, fp) != 1)
  124. goto error_NotRead;
  125. } else
  126. goto error_NotSupported1;
  127. #if 0
  128. printf("read:biSize: %lu\n", bi->biSize);
  129. printf("read:biWidth: %ld\n", bi->biWidth);
  130. printf("read:biHeight: %ld\n", bi->biHeight);
  131. printf("read:biPlanes: %u\n", bi->biPlanes);
  132. printf("read:biBitcount: %u\n", bi->biBitCount);
  133. if (bi->biSize == 40) {
  134. printf("read:biCompression: %lu\n", bi->biCompression);
  135. printf("read:biSizeImage: %lu\n", bi->biSizeImage);
  136. printf("read:biXPixPerMeter %ld\n", bi->biXPixPerMeter);
  137. printf("read:biYPixPerMeter %ld\n", bi->biYPixPerMeter);
  138. printf("read:biClrUsed: %lu\n", bi->biClrUsed);
  139. printf("read:biClrImporant: %lu\n", bi->biClrImportant);
  140. }
  141. #endif
  142. if (bi->biSize != 40)
  143. goto error_NotSupported1;
  144. if (bi->biPlanes != 1)
  145. goto error_NotSupported2;
  146. if (bi->biBitCount != 24 && bi->biBitCount != 8)
  147. goto error_NotSupported3;
  148. if (bi->biCompression != 0)
  149. goto error_NotSupported4;
  150. return 1;
  151.  
  152. error_NotSupported1:
  153. fprintf(stderr, "info header size: this format is not supported\n");
  154. return 0;
  155. error_NotSupported2:
  156. fprintf(stderr, "biPlanes: this format is not supported\n");
  157. return 0;
  158. error_NotSupported3:
  159. fprintf(stderr, "biBitCount: this format is not supported\n");
  160. return 0;
  161. error_NotSupported4:
  162. fprintf(stderr, "biCompression: this format is not supported\n");
  163. return 0;
  164. error_NotRead:
  165. fprintf(stderr, "cannot read bmp info header\n");
  166. return 0;
  167. }
  168.  
  169. int isFtellGood(FILE *fp, unsigned long pos) {
  170. return (unsigned long)ftell(fp) == pos;
  171. }
  172.  
  173. long iabs(long n) {
  174. return (n > 0) ? n : -n;
  175. }
  176.  
  177.  
  178. void task_read24(FILE *fp, BitmapFileHeader *bheader, BitmapInfoHeader *binfo,
  179. unsigned char **dataR, unsigned char **dataG,
  180. unsigned char **dataB)
  181. {
  182. long x, y, n;
  183. unsigned char dummy;
  184. int c;
  185. if (!isFtellGood(fp, bheader->bfOffBits)) {
  186. fprintf(stderr, "Header or Image Data is corrupted.\n");
  187. return;
  188. }
  189. *dataR = xmalloc(sizeof(char) * iabs(binfo->biWidth) * iabs(binfo->biHeight), IDRGB);
  190. *dataG = xmalloc(sizeof(char) * iabs(binfo->biWidth) * iabs(binfo->biHeight), IDRGB);
  191. *dataB = xmalloc(sizeof(char) * iabs(binfo->biWidth) * iabs(binfo->biHeight), IDRGB);
  192. if (*dataR == NULL || *dataG == NULL || *dataB == NULL) {
  193. fprintf(stderr, "cannot alloc. enough memory.\n");
  194. return;
  195. }
  196. for (y = 0; y < iabs(binfo->biHeight); y++) {
  197. c = 0;
  198. for (x = 0; x < iabs(binfo->biWidth); x++) {
  199. fread((*dataB + y * iabs(binfo->biWidth) + x), 1, 1, fp);
  200. fread((*dataG + y * iabs(binfo->biWidth) + x), 1, 1, fp);
  201. fread((*dataR + y * iabs(binfo->biWidth) + x), 1, 1, fp);
  202. c += 3;
  203. }
  204. while (c % 4 != 0) {
  205. fread(&dummy, 1, 1, fp);
  206. c++;
  207. }
  208. }
  209. n = iabs(binfo->biWidth) * 3;
  210. if (n % 4 > 0)
  211. n += 4 - (n % 4);
  212. binfo->biSizeImage = n * iabs(binfo->biHeight);
  213. bheader->bfSize = binfo->biSizeImage + binfo->biSize + 14;
  214. }
  215.  
  216. void task_read_palette(FILE *fp, BitmapFileHeader *bh, BitmapInfoHeader *bi,
  217. unsigned char **dataPalette)
  218. {
  219. int i, max;
  220. unsigned char dummy;
  221. if ((max = bi->biClrUsed) == 0)
  222. max = 256;
  223. *dataPalette = xmalloc(sizeof(char) * 3 * max, IDPALETTE);
  224. if (*dataPalette == NULL) {
  225. fprintf(stderr, "cannot alloc. enough memory.\n");
  226. return;
  227. }
  228. for (i = 0; i < max; i++) {
  229. fread((*dataPalette + 3 * i + 0), 1, 1, fp);
  230. fread((*dataPalette + 3 * i + 1), 1, 1, fp);
  231. fread((*dataPalette + 3 * i + 2), 1, 1, fp);
  232. fread(&dummy, 1, 1, fp);
  233. }
  234. }
  235.  
  236. void task_read8(FILE *fp, BitmapFileHeader *bheader, BitmapInfoHeader *binfo,
  237. unsigned char **dataR, unsigned char **dataG,
  238. unsigned char **dataB, unsigned char *dataPalette)
  239. {
  240. long x, y, n;
  241. unsigned char data;
  242. int c;
  243.  
  244. if (!isFtellGood(fp, bheader->bfOffBits)) {
  245. fprintf(stderr, "Header or Image Data is corrupted.\n");
  246. return;
  247. }
  248. *dataR = xmalloc(sizeof(char) * iabs(binfo->biWidth) * iabs(binfo->biHeight), IDRGB);
  249. *dataG = xmalloc(sizeof(char) * iabs(binfo->biWidth) * iabs(binfo->biHeight), IDRGB);
  250. *dataB = xmalloc(sizeof(char) * iabs(binfo->biWidth) * iabs(binfo->biHeight), IDRGB);
  251. if (*dataR == NULL || *dataG == NULL || *dataB == NULL) {
  252. fprintf(stderr, "cannot alloc. enough memory.\n");
  253. return;
  254. }
  255. for (y = 0; y < iabs(binfo->biHeight); y++) {
  256. c = 0;
  257. for (x = 0; x < iabs(binfo->biWidth); x++) {
  258. fread(&data, 1, 1, fp);
  259. *(*dataB + y * iabs(binfo->biWidth) + x) = dataPalette[3 * data + 0];
  260. *(*dataG + y * iabs(binfo->biWidth) + x) = dataPalette[3 * data + 1];
  261. *(*dataR + y * iabs(binfo->biWidth) + x) = dataPalette[3 * data + 2];
  262. c++;
  263. }
  264. while (c % 4 != 0) {
  265. fread(&data, 1, 1, fp);
  266. c++;
  267. }
  268. }
  269. n = iabs(binfo->biWidth) * 3;
  270. if (n % 4 > 0)
  271. n += 4 - (n % 4);
  272. binfo->biSizeImage = n * iabs(binfo->biHeight);
  273. bheader->bfSize = binfo->biSizeImage + binfo->biSize + 14;
  274. bheader->bfOffBits = 54;
  275. binfo->biBitCount = 24;
  276. binfo->biClrUsed = 0;
  277. binfo->biClrImportant = 0;
  278. }
  279.  
  280. void task_write_header(FILE *fp, BitmapFileHeader *bh) {
  281. assert(sizeof(unsigned short) == 2);
  282. assert(sizeof(unsigned long) == 4);
  283. fwrite(&(bh->bfType1), sizeof(unsigned char), 1, fp);
  284. fwrite(&(bh->bfType2), sizeof(unsigned char), 1, fp);
  285. fwrite(&(bh->bfSize), sizeof(unsigned long), 1, fp);
  286. fwrite(&(bh->bfReserved1), sizeof(unsigned short), 1, fp);
  287. fwrite(&(bh->bfReserved2), sizeof(unsigned short), 1, fp);
  288. fwrite(&(bh->bfOffBits), sizeof(unsigned long), 1, fp);
  289. #if 0
  290. printf("write:bfType1: %c\n", bh->bfType1);
  291. printf("write:bfType2: %c\n", bh->bfType2);
  292. printf("write:bfSize: %lu\n", bh->bfSize);
  293. printf("write:bfReserved1: %u\n", bh->bfReserved1);
  294. printf("write:bfReserved2: %u\n", bh->bfReserved2);
  295. printf("write:bfOffBits: %lu\n", bh->bfOffBits);
  296. #endif
  297. }
  298.  
  299. void task_write_info(FILE *fp, BitmapInfoHeader *bi) {
  300. assert(sizeof(unsigned short) == 2);
  301. assert(sizeof(unsigned long) == 4);
  302. assert(sizeof(long) == 4);
  303. fwrite(&(bi->biSize), sizeof(unsigned long), 1, fp);
  304. fwrite(&(bi->biWidth), sizeof(long), 1, fp);
  305. fwrite(&(bi->biHeight), sizeof(long), 1, fp);
  306. fwrite(&(bi->biPlanes), sizeof(unsigned short), 1, fp);
  307. fwrite(&(bi->biBitCount), sizeof(unsigned short), 1, fp);
  308. fwrite(&(bi->biCompression), sizeof(unsigned long), 1, fp);
  309. fwrite(&(bi->biSizeImage), sizeof(unsigned long), 1, fp);
  310. fwrite(&(bi->biXPixPerMeter), sizeof(long), 1, fp);
  311. fwrite(&(bi->biYPixPerMeter), sizeof(long), 1, fp);
  312. fwrite(&(bi->biClrUsed), sizeof(unsigned long), 1, fp);
  313. fwrite(&(bi->biClrImportant), sizeof(unsigned long), 1, fp);
  314. #if 0
  315. printf("write:biSize: %lu\n", bi->biSize);
  316. printf("write:biWidth: %ld\n", bi->biWidth);
  317. printf("write:biHeight: %ld\n", bi->biHeight);
  318. printf("write:biPlanes: %u\n", bi->biPlanes);
  319. printf("write:biBitcount: %u\n", bi->biBitCount);
  320. printf("write:biCompression: %lu\n", bi->biCompression);
  321. printf("write:biSizeImage: %lu\n", bi->biSizeImage);
  322. printf("write:biXPixPerMeter %ld\n", bi->biXPixPerMeter);
  323. printf("write:biYPixPerMeter %ld\n", bi->biYPixPerMeter);
  324. printf("write:biClrUsed: %lu\n", bi->biClrUsed);
  325. printf("write:biClrImporant: %lu\n", bi->biClrImportant);
  326. #endif
  327. }
  328.  
  329. void task_write24(FILE *fp,
  330. BitmapFileHeader *bh, BitmapInfoHeader *bi,
  331. unsigned char *dataR,
  332. unsigned char *dataG,
  333. unsigned char *dataB) {
  334. int x, y;
  335. int c;
  336. unsigned char dummy = '\0';
  337. task_write_header(fp, bh);
  338. task_write_info(fp, bi);
  339. for (y = 0; y < iabs(bi->biHeight); y++) {
  340. c = 0;
  341. for (x = 0; x < iabs(bi->biWidth); x++) {
  342. fwrite(&dataB[y * iabs(bi->biWidth) + x], 1, 1, fp);
  343. fwrite(&dataG[y * iabs(bi->biWidth) + x], 1, 1, fp);
  344. fwrite(&dataR[y * iabs(bi->biWidth) + x], 1, 1, fp);
  345. c += 3;
  346. }
  347. while (c % 4 != 0) {
  348. fwrite(&dummy, 1, 1, fp);
  349. c++;
  350. }
  351. }
  352. }
  353.  
  354. /* ------------------------------------------------------------------------- */
  355. struct BMP24 {
  356. BitmapFileHeader bh;
  357. BitmapInfoHeader bi;
  358. unsigned char *dataR;
  359. unsigned char *dataG;
  360. unsigned char *dataB;
  361. unsigned char *dataPalette;
  362. };
  363.  
  364. int BMP24_read(FILE *fp, struct BMP24 *bmp) {
  365. if (!bmHeaderCheck(fp, &(bmp->bh)))
  366. return 0;
  367. if (!bmInfoHeaderCheck(fp, &(bmp->bi)))
  368. return 0;
  369. bmp->dataR = bmp->dataG = bmp->dataB = bmp->dataPalette = NULL;
  370. if ((bmp->bi).biBitCount == 24) {
  371. task_read24(fp, &(bmp->bh), &(bmp->bi),
  372. &(bmp->dataR), &(bmp->dataG), &(bmp->dataB));
  373. } else if ((bmp->bi).biBitCount == 8) {
  374. task_read_palette(fp, &bmp->bh, &bmp->bi, &bmp->dataPalette);
  375. task_read8(fp, &bmp->bh, &bmp->bi,
  376. &bmp->dataR, &bmp->dataG, &bmp->dataB, bmp->dataPalette);
  377. xfree(bmp->dataPalette, IDPALETTE);
  378. bmp->dataPalette = NULL;
  379. }
  380. if (!(bmp->dataR && bmp->dataG && bmp->dataB)) {
  381. xfree(bmp->dataR, IDRGB);
  382. xfree(bmp->dataG, IDRGB);
  383. xfree(bmp->dataB, IDRGB);
  384. return 0;
  385. }
  386. return 1;
  387. }
  388.  
  389. void BMP24_write(FILE *fp, struct BMP24 *bmp) {
  390. task_write24(fp, &bmp->bh, &bmp->bi,
  391. bmp->dataR, bmp->dataG, bmp->dataB);
  392. }
  393.  
  394. void _BMP24_allocation(struct BMP24 **w_bmp, long width, long height) {
  395. int n;
  396. *w_bmp = xmalloc(sizeof(struct BMP24), IDBMP);
  397. if (*w_bmp == NULL) {
  398. fprintf(stderr, "error(bmp24)\n");
  399. return;
  400. }
  401. n = width * 3;
  402. if (n % 4 > 0)
  403. n += 4 - (n % 4);
  404. (*w_bmp)->bi.biSizeImage = n * height;
  405. (*w_bmp)->bi.biSize = 40;
  406. (*w_bmp)->bh.bfSize = (*w_bmp)->bi.biSizeImage + (*w_bmp)->bi.biSize + 14;
  407.  
  408. (*w_bmp)->bh.bfType1 = 'B';
  409. (*w_bmp)->bh.bfType2 = 'M';
  410. (*w_bmp)->bh.bfReserved1 = 0;
  411. (*w_bmp)->bh.bfReserved2 = 0;
  412. (*w_bmp)->bh.bfOffBits = 54;
  413.  
  414. (*w_bmp)->bi.biPlanes = 1;
  415. (*w_bmp)->bi.biBitCount = 24;
  416. (*w_bmp)->bi.biCompression = 0;
  417. (*w_bmp)->bi.biHeight = height;
  418. (*w_bmp)->bi.biWidth = width;
  419. (*w_bmp)->bi.biClrUsed = 0;
  420. (*w_bmp)->bi.biClrImportant = 0;
  421. (*w_bmp)->bi.biXPixPerMeter = 30;
  422. (*w_bmp)->bi.biYPixPerMeter = 30;
  423. (*w_bmp)->dataR = (*w_bmp)->dataG = (*w_bmp)->dataB = NULL;
  424. (*w_bmp)->dataPalette = NULL;
  425. for (;;) {
  426. if (((*w_bmp)->dataR = xmalloc(width * height, IDRGB)) == 0)
  427. break;
  428. if (((*w_bmp)->dataG = xmalloc(width * height, IDRGB)) == 0)
  429. break;
  430. if (((*w_bmp)->dataB = xmalloc(width * height, IDRGB)) == 0)
  431. break;
  432. /* OK finished */
  433. return;
  434. }
  435. /* exception */
  436. xfree((*w_bmp)->dataR, IDRGB);
  437. xfree((*w_bmp)->dataG, IDRGB);
  438. xfree((*w_bmp)->dataB, IDRGB);
  439. xfree(*w_bmp, IDBMP);
  440. *w_bmp = 0;
  441. return;
  442. }
  443.  
  444. void BMP24_release(struct BMP24 *bmp) {
  445. if (bmp->dataR) xfree(bmp->dataR, IDRGB);
  446. if (bmp->dataG) xfree(bmp->dataG, IDRGB);
  447. if (bmp->dataB) xfree(bmp->dataB, IDRGB);
  448. if (bmp->dataPalette) xfree(bmp->dataPalette, IDPALETTE);
  449. }
  450.  
  451. /* ------------------------------------------------------------------------- */
  452. #define BUFFSIZE 3 /* >= 2 */
  453. char *mygetline(FILE *fp) {
  454. static char inbuff[BUFFSIZE];
  455. char *outbuff_malloc, *tmpbuff;
  456. char *p, *r;
  457. int fEOL;
  458.  
  459. if ((outbuff_malloc = xmalloc(1, ID_GETLINE)) == NULL) {
  460. return NULL;
  461. }
  462. *outbuff_malloc = '\0';
  463. fEOL = 0;
  464. do {
  465. r = fgets(inbuff, BUFFSIZE, fp);
  466. if (r == NULL)
  467. break;
  468. for (p = inbuff; *p != '\0'; p++)
  469. ;
  470. if (*(p - 1) == '\n')
  471. fEOL = 1;
  472. if ((tmpbuff = xrealloc(outbuff_malloc, strlen(outbuff_malloc) + strlen(inbuff) + 1, ID_GETLINE)) == NULL) {
  473. xfree(outbuff_malloc, ID_GETLINE);
  474. return NULL;
  475. }
  476. strcat(tmpbuff, inbuff);
  477. outbuff_malloc = tmpbuff;
  478. } while (!fEOL);
  479. if (strlen(outbuff_malloc) > 0) {
  480. for (p = outbuff_malloc; *p != '\0'; p++)
  481. ;
  482. if (*(p - 1) == '\n')
  483. *(p - 1) = '\0';
  484. return outbuff_malloc;
  485. }
  486. xfree(outbuff_malloc, ID_GETLINE);
  487. return NULL;
  488. }
  489.  
  490. char *cutToken(char *p, char **s) {
  491. char *t, *q;
  492. int flag;
  493. if (p == 0)
  494. return 0;
  495. flag = 0;
  496. for (q = p; *q == ' ' && *q != '\0'; q++)
  497. ;
  498. if (*q == '\0')
  499. return 0;
  500. t = q;
  501. q++;
  502. for (; *q != ' ' && *q != '\0'; q++)
  503. ;
  504. if (*q == '\0')
  505. flag = 1;
  506. *q = '\0';
  507. if (flag)
  508. *s = 0;
  509. else
  510. *s = q + 1;
  511. return t;
  512. }
  513.  
  514. void task_pgm2bmp(FILE *fppgm, FILE *fpbmp) {
  515. struct BMP24 *bmp;
  516. long width, height, y, x, d;
  517. char *line, *p, *q;
  518. int c;
  519.  
  520. /* header */
  521. if ((line = mygetline(fppgm)) == 0) {
  522. fprintf(stderr, "cannot read pgm file: header\n");
  523. return;
  524. }
  525. if (strcmp(line, "P2") != 0) {
  526. fprintf(stderr, "pgm header %s: not supported\n", line);
  527. xfree(line, ID_GETLINE);
  528. return;
  529. }
  530. xfree(line, ID_GETLINE);
  531.  
  532. /* width, height */
  533. if ((line = mygetline(fppgm)) == 0) {
  534. fprintf(stderr, "cannot read pgm file: width/height\n");
  535. return;
  536. }
  537. if (sscanf(line, "%ld %ld", &width, &height) != 2) {
  538. fprintf(stderr, "pgm width/height: bad format\n");
  539. xfree(line, ID_GETLINE);
  540. return;
  541. }
  542. xfree(line, ID_GETLINE);
  543.  
  544. /* depth */
  545. if ((line = mygetline(fppgm)) == 0) {
  546. fprintf(stderr, "cannot read pgm file: depth\n");
  547. return;
  548. }
  549. if (sscanf(line, "%ld", &d) != 1) {
  550. fprintf(stderr, "pgm depth: bad format\n");
  551. xfree(line, ID_GETLINE);
  552. return;
  553. }
  554. xfree(line, ID_GETLINE);
  555.  
  556. bmp = 0;
  557. _BMP24_allocation(&bmp, width, height);
  558. if (bmp == 0) {
  559. fprintf(stderr, "cannot allocate enough memory(_BMP24_allocation)\n");
  560. return;
  561. }
  562.  
  563. for (y = height - 1; y >= 0; --y) {
  564. if ((line = mygetline(fppgm)) == 0) {
  565. fprintf(stderr, "pgm body: bad format(too small : height).\n");
  566. xfree(line, ID_GETLINE);
  567. return;
  568. }
  569. p = line;
  570. for (x = 0; x < width; x++) {
  571. if ((q = cutToken(p, &p)) == 0) {
  572. fprintf(stderr, "pgm body: bad format(too small : height).\n");
  573. xfree(line, ID_GETLINE);
  574. BMP24_release(bmp);
  575. xfree(bmp, IDBMP);
  576. return;
  577. }
  578. c = atoi(q);
  579. bmp->dataR[y * width + x] = bmp->dataG[y * width + x] = bmp->dataB[y * width + x] = (unsigned char)(255 * c / d);
  580. }
  581. xfree(line, ID_GETLINE);
  582. }
  583. BMP24_write(fpbmp, bmp);
  584. BMP24_release(bmp);
  585. xfree(bmp, IDBMP);
  586. }
  587.  
  588. int main(int argc, char **argv) {
  589. FILE *fpbmp, *fppgm;
  590. if (argc != 3) {
  591. fprintf(stderr, "usage: %s <filename:pgm> <filename:bmp>\n", argv[0]);
  592. exit(-1);
  593. }
  594. if ((fppgm = fopen(argv[1], "r")) == 0) {
  595. fprintf(stderr, "cannot open the .pgm file for reading\n");
  596. exit(-1);
  597. }
  598. if ((fpbmp = fopen(argv[2], "w")) == 0) {
  599. fprintf(stderr, "cannot open the .bmp file for writing\n");
  600. fclose(fpbmp);
  601. exit(-1);
  602. }
  603. task_pgm2bmp(fppgm, fpbmp);
  604. fclose(fpbmp);
  605. fclose(fppgm);
  606. xmallocdump();
  607. return 0;
  608. }
  609. /* end */
  610.  
Runtime error #stdin #stdout #stderr 0s 5436KB
stdin
Standard input is empty
stdout
Standard output is empty
stderr
usage: ./prog <filename:pgm> <filename:bmp>