§ Как устроен формат
Этот формат переводится как Portable Pixel Map и настолько прост, что даже BMP кажется сложным.Первые строки в файле PPM пишутся так:
P6 # Здесь может быть комментарий 640 400 255
- Здесь P6 означает "магическое число формата". После P6 ставится символ \n переноса строки. Тут может быть не только P6, но и P3. Этот формат можно посмотреть тут.
- Комментариев может быть сколько угодно, они начинаются с #
- Сразу после комментария идет размер по ширине и высоте
- 255 означает что далее идет RGB последовательность
§ Код для записи файла
В data находятся числа в формате int, причем blue-компонента находится в младшем байте. Альфа-канал не записывается.1int write_ppm(const char* filename, int width, int height, int data[]) { 2 3 FILE* fp = fopen(filename, "wb"); 4 5 char buf[256]; 6 7 if (fp) { 8 9 sprintf(buf, "P6\n# G++ HELLO WORLD\n%d %d\n255\n", width, height); 10 fputs(buf, fp); 11 12 for (int y = 0; y < height; y++) 13 for (int x = 0; x < width; x++) { 14 15 int cl = data[y*width+x]; 16 17 buf[0] = cl>>16; 18 buf[1] = cl>>8; 19 buf[2] = cl; 20 21 fwrite(buf, 1, 3, fp); 22 } 23 24 fclose(fp); 25 } 26}Тестовый код для записи в файл
1int main(int argc, char* argv[]) { 2 3 int data[640*480]; 4 5 for (int y = 0; y < 480; y++) 6 for (int x = 0; x < 640; x++) { 7 data[640*y + x] = x*y; 8 } 9 10 write_ppm("file.ppm", 640, 480, data); 11 12 return 0; 13}
§ Код для чтения из PPM
Чтение из файла, создание новой области памяти с Uint значениями RGB.1unsigned int* load_ppm(const char* fn) { 2 3 char s[256]; 4 unsigned char m[3]; 5 int w = 0, h = 0; 6 7 FILE* fp = fopen(fn, "rb"); 8 if (fp) { 9 10 fgets(s, 256, fp); 11 if (s[0] == 'P' && s[1] == '6') { 12 13 // Игнорировать комментарии 14 do { fgets(s, 256, fp); } while (s[0] == '#'); 15 sscanf(s, "%d %d", &w, &h); 16 fgets(s, 256, fp); // Должен быть 255 17 18 // Загрузка текстуры в память 19 unsigned int* tmp = (unsigned int*)malloc(w * h * sizeof(unsigned int)); 20 21 for (int i = 0; i < h; i++) 22 for (int j = 0; j < w; j++) { 23 24 fread(m, 1, 3, fp); 25 tmp[i*w + j] = m[0] + m[1]*256 + m[2]*65536; 26 } 27 28 fclose(fp); 29 return tmp; 30 31 } else { 32 33 fclose(fp); 34 printf("Error with signature %s\n", fn); exit(2); 35 } 36 37 } else { 38 printf("Texture %s not found\n", fn); 39 exit(1); 40 } 41 42 return NULL; 43}