static int sgi_read(ByteIOContext *f, int (*alloc_cb)(void *opaque, AVImageInfo *info), void *opaque) { SGIInfo sgi_info, *s = &sgi_info; AVImageInfo info1, *info = &info1; int ret; read_sgi_header(f, s); if (s->bytes_per_channel != 1) { return AVERROR_INVALIDDATA; } /* check for supported image dimensions */ if (s->dimension != 2 && s->dimension != 3) { return AVERROR_INVALIDDATA; } if (s->zsize == SGI_GRAYSCALE) { info->pix_fmt = PIX_FMT_GRAY8; } else if (s->zsize == SGI_RGB) { info->pix_fmt = PIX_FMT_RGB24; } else if (s->zsize == SGI_RGBA) { info->pix_fmt = PIX_FMT_RGBA32; } else { return AVERROR_INVALIDDATA; } info->width = s->xsize; info->height = s->ysize; ret = alloc_cb(opaque, info); if (ret) return ret; if (s->rle) { return read_rle_sgi(s, &info->pict, f); } else { return read_uncompressed_sgi(s, &info->pict, f); } return 0; /* not reached */ }
/* decode a frame */ static mp_image_t *decode(sh_video_t *sh, void *raw, int len, int flags) { SGIInfo *info = sh->context; unsigned char *data = raw; mp_image_t *mpi; if (len <= 0) { return NULL; /* skip frame */ } read_sgi_header(data, info); /* make sure this is an SGI image file */ if (info->magic != SGI_MAGIC) { mp_msg(MSGT_DECVIDEO, MSGL_INFO, "Bad magic number in image.\n"); return NULL; } /* check image depth */ if (info->bytes_per_channel != 1) { mp_msg(MSGT_DECVIDEO, MSGL_INFO, "Unsupported bytes per channel value %i.\n", info->bytes_per_channel); return NULL; } /* check image dimension */ if (info->dimension != 2 && info->dimension != 3) { mp_msg(MSGT_DECVIDEO, MSGL_INFO, "Unsupported image dimension %i.\n", info->dimension); return NULL; } /* change rgba images to rgb so alpha channel will be ignored */ if (info->zsize == SGI_RGBA_IMAGE) { info->zsize = SGI_RGB_IMAGE; } /* check image depth */ if (info->zsize != SGI_RGB_IMAGE && info->zsize != SGI_GRAYSCALE_IMAGE) { mp_msg(MSGT_DECVIDEO, MSGL_INFO, "Unsupported image depth.\n"); return NULL; } /* (re)init libvo if image size is changed */ if (last_x != info->xsize || last_y != info->ysize) { last_x = info->xsize; last_y = info->ysize; if (!mpcodecs_config_vo(sh, info->xsize, info->ysize, outfmt)) { mp_msg(MSGT_DECVIDEO, MSGL_INFO, "Config vo failed:\n"); return NULL; } } if (!(mpi = mpcodecs_get_image(sh, MP_IMGTYPE_TEMP, MP_IMGFLAG_ACCEPT_STRIDE, info->xsize, info->ysize))) { return NULL; } if (info->rle) { decode_rle_sgi(info, data, mpi); } else { decode_uncompressed_sgi(info, data, mpi); } return mpi; }