comparison libvo/gl_common.c @ 32393:98fda5253e80

Extract code to read a pnm file into a separate function.
author reimar
date Sun, 10 Oct 2010 11:20:57 +0000
parents 0ffe9f97fc9f
children 58232aeb3fdd
comparison
equal deleted inserted replaced
32392:7fd2de8d6f32 32393:98fda5253e80
574 ungetc(c, f); 574 ungetc(c, f);
575 } 575 }
576 576
577 #define MAXDIM (16 * 1024) 577 #define MAXDIM (16 * 1024)
578 578
579 static uint8_t *read_pnm(FILE *f, int *width, int *height,
580 int *bytes_per_pixel, int *maxval) {
581 uint8_t *data;
582 int type;
583 unsigned w, h, m, val, bpp;
584 *width = *height = *bytes_per_pixel = *maxval = 0;
585 ppm_skip(f);
586 if (fgetc(f) != 'P')
587 return NULL;
588 type = fgetc(f);
589 if (type != '5' && type != '6')
590 return NULL;
591 ppm_skip(f);
592 if (fscanf(f, "%u", &w) != 1)
593 return NULL;
594 ppm_skip(f);
595 if (fscanf(f, "%u", &h) != 1)
596 return NULL;
597 ppm_skip(f);
598 if (fscanf(f, "%u", &m) != 1)
599 return NULL;
600 val = fgetc(f);
601 if (!isspace(val))
602 return NULL;
603 if (w > MAXDIM || h > MAXDIM)
604 return NULL;
605 bpp = (m > 255) ? 2 : 1;
606 if (type == '6')
607 bpp *= 3;
608 data = malloc(w * h * bpp);
609 if (fread(data, w * bpp, h, f) != h) {
610 free(data);
611 return NULL;
612 }
613 *width = w;
614 *height = h;
615 *bytes_per_pixel = bpp;
616 *maxval = m;
617 return data;
618 }
619
579 /** 620 /**
580 * \brief creates a texture from a PPM file 621 * \brief creates a texture from a PPM file
581 * \param target texture taget, usually GL_TEXTURE_2D 622 * \param target texture taget, usually GL_TEXTURE_2D
582 * \param fmt internal texture format, 0 for default 623 * \param fmt internal texture format, 0 for default
583 * \param filter filter used for scaling, e.g. GL_LINEAR 624 * \param filter filter used for scaling, e.g. GL_LINEAR
588 * \return 0 on error, 1 otherwise 629 * \return 0 on error, 1 otherwise
589 * \ingroup gltexture 630 * \ingroup gltexture
590 */ 631 */
591 int glCreatePPMTex(GLenum target, GLenum fmt, GLint filter, 632 int glCreatePPMTex(GLenum target, GLenum fmt, GLint filter,
592 FILE *f, int *width, int *height, int *maxval) { 633 FILE *f, int *width, int *height, int *maxval) {
593 unsigned w, h, m, val, bpp; 634 int w, h, m, bpp;
594 char *data;
595 GLenum type; 635 GLenum type;
596 ppm_skip(f); 636 uint8_t *data = read_pnm(f, &w, &h, &bpp, &m);
597 if (fgetc(f) != 'P' || fgetc(f) != '6') 637 if (!data || (bpp != 3 && bpp != 6)) {
638 free(data);
598 return 0; 639 return 0;
599 ppm_skip(f); 640 }
600 if (fscanf(f, "%u", &w) != 1)
601 return 0;
602 ppm_skip(f);
603 if (fscanf(f, "%u", &h) != 1)
604 return 0;
605 ppm_skip(f);
606 if (fscanf(f, "%u", &m) != 1)
607 return 0;
608 val = fgetc(f);
609 if (!isspace(val))
610 return 0;
611 if (w > MAXDIM || h > MAXDIM)
612 return 0;
613 bpp = (m > 255) ? 6 : 3;
614 data = malloc(w * h * bpp);
615 if (fread(data, w * bpp, h, f) != h)
616 return 0;
617 if (!fmt) { 641 if (!fmt) {
618 fmt = (m > 255) ? hqtexfmt : 3; 642 fmt = bpp == 6 ? hqtexfmt : 3;
619 if (fmt == GL_FLOAT_RGB32_NV && target != GL_TEXTURE_RECTANGLE) 643 if (fmt == GL_FLOAT_RGB32_NV && target != GL_TEXTURE_RECTANGLE)
620 fmt = GL_RGB16; 644 fmt = GL_RGB16;
621 } 645 }
622 type = m > 255 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_BYTE; 646 type = bpp == 6 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_BYTE;
623 glCreateClearTex(target, fmt, GL_RGB, type, filter, w, h, 0); 647 glCreateClearTex(target, fmt, GL_RGB, type, filter, w, h, 0);
624 glUploadTex(target, GL_RGB, type, 648 glUploadTex(target, GL_RGB, type,
625 data, w * bpp, 0, 0, w, h, 0); 649 data, w * bpp, 0, 0, w, h, 0);
626 free(data); 650 free(data);
627 if (width) *width = w; 651 if (width) *width = w;