Mercurial > mplayer.hg
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; |