Advertisement
roninkoi

PPM image parser

Aug 29th, 2019
300
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 2.39 KB | None | 0 0
  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. #include <string.h>
  4.  
  5. #define TEX_MAX 0x100000
  6.  
  7. // loads a ppm image into an array of bytes (RGB)
  8. unsigned char *ppmLoader(char *path, int *texWidth, int *texHeight)
  9. {
  10.     char *data = NULL;
  11.     FILE *fp;
  12.     size_t fsize;
  13.  
  14.     fp = fopen(path, "r");
  15.  
  16.     if (!fp) {
  17.         printf("Not found: %s\n", path);
  18.         exit(1);
  19.     }
  20.  
  21.     data = calloc(TEX_MAX, sizeof(char *));
  22.     fsize = fread(data, 1, TEX_MAX, fp);
  23.  
  24.     fclose(fp);
  25.  
  26.     char *c = (char *) malloc(TEX_MAX);
  27.  
  28.     int width = 0, height = 0;
  29.     int dp = 0;
  30.     int ds = 0;
  31.  
  32.     float maxval = 0.0f;
  33.  
  34.     unsigned char *returns = NULL;
  35.     int ri = 0;
  36.  
  37.     for (int i = 0; data[i] && i < TEX_MAX; ++i) {
  38.         int j = 0;
  39.  
  40.         ds = (dp ? data[i] != ' ' : 1);
  41.  
  42.         for (j = 0; data[i] != '\n' && data[i] != '\r' && ds && data[i]; ++j) {
  43.             c[j] = data[i];
  44.             ++i;
  45.         }
  46.  
  47.         c[j] = 0;
  48.  
  49.         if (c[0] != '#' && c[0] != 'P') {
  50.             if (width == 0 && height == 0) { // parse dimensions
  51.                 char ws[6];
  52.                 char hs[6];
  53.  
  54.                 int k = 0;
  55.                 for (j = 0; c[j] != ' ' && c[j]; ++j) { // texture width
  56.                     ws[k] = c[j];
  57.                     ++k;
  58.                 }
  59.  
  60.                 ws[k] = 0;
  61.  
  62.                 k = 0;
  63.                 for (j = 0; c[j] != ' ' && c[j]; ++j) { // texture height
  64.                     hs[k] = c[j];
  65.                     ++k;
  66.                 }
  67.  
  68.                 hs[k] = 0;
  69.  
  70.                 width = atoi(ws);
  71.                 height = atoi(hs);
  72.  
  73.                 returns = (unsigned char *) malloc(sizeof(unsigned char) * width * height * 3);
  74.  
  75.                 dp = 1;
  76.             }
  77.             else { // parse texture data
  78.                 if (maxval == 0.0f) {
  79.                     maxval = (float) atoi(c);
  80.  
  81.                     continue; // proper data starts after
  82.                 }
  83.  
  84.                 float val = (float) atoi(c) / maxval;
  85.  
  86.                 if (ri < width * height * 3)
  87.                     returns[ri] = (unsigned char) (val * 255.0f);
  88.  
  89.                 ++ri;
  90.             }
  91.         }
  92.     }
  93.  
  94.     free(data);
  95.     free(c);
  96.  
  97.     *texWidth = width;
  98.     *texHeight = height;
  99.  
  100.     return returns;
  101. }
  102.  
  103. unsigned char *ppmLoaderAlpha(char *path, int *texWidth, int *texHeight, int r, int g, int b)
  104. {
  105.     unsigned char *rgb = ppmLoader(path, texWidth, texHeight);
  106.  
  107.     unsigned char *rgba = (unsigned char *) malloc(sizeof(unsigned char) * (*texWidth) * (*texHeight) * 4);
  108.  
  109.     for (int i = 0; i < (*texWidth) * (*texHeight); i += 1) {
  110.         rgba[i * 4 + 0] = rgb[i * 3 + 0];
  111.         rgba[i * 4 + 1] = rgb[i * 3 + 1];
  112.         rgba[i * 4 + 2] = rgb[i * 3 + 2];
  113.         rgba[i * 4 + 3] = 255;
  114.  
  115.         if (rgb[i * 3 + 0] == r && rgb[i * 3 + 1] == g && rgb[i * 3 + 2] == b) { // bitmasking
  116.             rgba[i * 4 + 3] = 0;
  117.         }
  118.     }
  119.  
  120.     free(rgb);
  121.  
  122.     return rgba;
  123. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement