LCOV - code coverage report
Current view: top level - filters - dec_img.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 62 68 91.2 %
Date: 2021-04-29 23:48:07 Functions: 3 3 100.0 %

          Line data    Source code
       1             : /*
       2             :  *                      GPAC - Multimedia Framework C SDK
       3             :  *
       4             :  *                      Authors: Jean Le Feuvre
       5             :  *                      Copyright (c) Telecom ParisTech 2000-2021
       6             :  *                                      All rights reserved
       7             :  *
       8             :  *  This file is part of GPAC / libjpeg and libpng decoder filter
       9             :  *
      10             :  *  GPAC is free software; you can redistribute it and/or modify
      11             :  *  it under the terms of the GNU Lesser General Public License as published by
      12             :  *  the Free Software Foundation; either version 2, or (at your option)
      13             :  *  any later version.
      14             :  *
      15             :  *  GPAC is distributed in the hope that it will be useful,
      16             :  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
      17             :  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      18             :  *  GNU Lesser General Public License for more details.
      19             :  *
      20             :  *  You should have received a copy of the GNU Lesser General Public
      21             :  *  License along with this library; see the file COPYING.  If not, write to
      22             :  *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
      23             :  *
      24             :  */
      25             : 
      26             : #include <gpac/filters.h>
      27             : #include <gpac/constants.h>
      28             : #include <gpac/avparse.h>
      29             : 
      30             : typedef struct
      31             : {
      32             :         u32 codecid;
      33             :         GF_FilterPid *ipid, *opid;
      34             :         u32 width, height, pixel_format, BPP;
      35             : } GF_IMGDecCtx;
      36             : 
      37         227 : static GF_Err imgdec_configure_pid(GF_Filter *filter, GF_FilterPid *pid, Bool is_remove)
      38             : {
      39             :         const GF_PropertyValue *prop;
      40         227 :         GF_IMGDecCtx *ctx = (GF_IMGDecCtx *) gf_filter_get_udta(filter);
      41             : 
      42             :         //disconnect of src pid (not yet supported)
      43         227 :         if (is_remove) {
      44          18 :                 if (ctx->opid) {
      45          18 :                         gf_filter_pid_remove(ctx->opid);
      46          18 :                         ctx->opid = NULL;
      47             :                 }
      48          18 :                 ctx->ipid = NULL;
      49          18 :                 return GF_OK;
      50             :         }
      51         209 :         if (! gf_filter_pid_check_caps(pid))
      52             :                 return GF_NOT_SUPPORTED;
      53             : 
      54         208 :         prop = gf_filter_pid_get_property(pid, GF_PROP_PID_CODECID);
      55         208 :         if (!prop) return GF_NOT_SUPPORTED;
      56         208 :         ctx->codecid = prop->value.uint;
      57         208 :         ctx->ipid = pid;
      58             : 
      59         208 :         if (!ctx->opid) {
      60         208 :                 ctx->opid = gf_filter_pid_new(filter);
      61             :         }
      62             :         //copy properties at init or reconfig
      63         208 :         gf_filter_pid_copy_properties(ctx->opid, ctx->ipid);
      64         208 :         gf_filter_pid_set_property(ctx->opid, GF_PROP_PID_CODECID, & PROP_UINT( GF_CODECID_RAW ));
      65             : 
      66         208 :         if (ctx->codecid==GF_CODECID_JPEG) {
      67         113 :                 gf_filter_set_name(filter, "imgdec:libjpeg");
      68          95 :         } else if (ctx->codecid==GF_CODECID_PNG) {
      69          95 :                 gf_filter_set_name(filter, "imgdec:libpng");
      70             :         }
      71             :         return GF_OK;
      72             : }
      73             : 
      74         480 : static GF_Err imgdec_process(GF_Filter *filter)
      75             : {
      76             : #ifndef GPAC_DISABLE_AV_PARSERS
      77             :         GF_Err e;
      78             :         GF_FilterPacket *pck;
      79             :         u8 *data, *output;
      80             :         u32 size;
      81         480 :         GF_IMGDecCtx *ctx = (GF_IMGDecCtx *) gf_filter_get_udta(filter);
      82             : 
      83         480 :         pck = gf_filter_pid_get_packet(ctx->ipid);
      84         480 :         if (!pck) {
      85         271 :                         if (gf_filter_pid_is_eos(ctx->ipid)) {
      86         251 :                         gf_filter_pid_set_eos(ctx->opid);
      87         251 :                         return GF_EOS;
      88             :                 }
      89             :                 return GF_OK;
      90             :         }
      91         209 :         data = (char *) gf_filter_pck_get_data(pck, &size);
      92             : 
      93         209 :         if ((ctx->codecid == GF_CODECID_JPEG) || (ctx->codecid == GF_CODECID_PNG)) {
      94             :                 GF_FilterPacket *dst_pck;
      95         209 :                 u32 out_size = 0;
      96         209 :                 u32 w = ctx->width;
      97         209 :                 u32 h = ctx->height;
      98         209 :                 u32 pf = ctx->pixel_format;
      99             : 
     100         209 :                 if (ctx->codecid == GF_CODECID_JPEG) {
     101         113 :                         e = gf_img_jpeg_dec(data, size, &ctx->width, &ctx->height, &ctx->pixel_format, NULL, &out_size, ctx->BPP);
     102             :                 } else {
     103          96 :                         e = gf_img_png_dec(data, size, &ctx->width, &ctx->height, &ctx->pixel_format, NULL, &out_size);
     104             :                 }
     105             : 
     106         209 :                 if (e != GF_BUFFER_TOO_SMALL) {
     107           0 :                         gf_filter_pid_drop_packet(ctx->ipid);
     108           0 :                         return e;
     109             :                 }
     110         209 :                 if ((w != ctx->width) || (h!=ctx->height) || (pf!=ctx->pixel_format)) {
     111         204 :                         switch (ctx->pixel_format) {
     112           0 :                         case GF_PIXEL_GREYSCALE:
     113           0 :                                 ctx->BPP = 1;
     114           0 :                                 break;
     115         112 :                         case GF_PIXEL_RGB:
     116         112 :                                 ctx->BPP = 3;
     117         112 :                                 break;
     118          92 :                         case GF_PIXEL_RGBA:
     119          92 :                                 ctx->BPP = 4;
     120          92 :                                 break;
     121             :                         }
     122         204 :                         gf_filter_pid_set_property(ctx->opid, GF_PROP_PID_WIDTH, & PROP_UINT(ctx->width));
     123         204 :                         gf_filter_pid_set_property(ctx->opid, GF_PROP_PID_HEIGHT, & PROP_UINT(ctx->height));
     124         204 :                         gf_filter_pid_set_property(ctx->opid, GF_PROP_PID_PIXFMT, & PROP_UINT(ctx->pixel_format));
     125         204 :                         gf_filter_pid_set_property(ctx->opid, GF_PROP_PID_STRIDE, &PROP_UINT(ctx->BPP*ctx->width) );
     126             :                 }
     127         209 :                 dst_pck = gf_filter_pck_new_alloc(ctx->opid, out_size, &output);
     128         209 :                 if (!dst_pck) return GF_OUT_OF_MEM;
     129             : 
     130         209 :                 if (ctx->codecid == GF_CODECID_JPEG) {
     131         113 :                         e = gf_img_jpeg_dec(data, size, &ctx->width, &ctx->height, &ctx->pixel_format, output, &out_size, ctx->BPP);
     132             :                 } else {
     133          96 :                         e = gf_img_png_dec(data, size, &ctx->width, &ctx->height, &ctx->pixel_format, output, &out_size);
     134             :                 }
     135             : 
     136         209 :                 if (e) {
     137           0 :                         gf_filter_pck_discard(dst_pck);
     138             :                 } else {
     139         209 :                         gf_filter_pck_merge_properties(pck, dst_pck);
     140         209 :                         gf_filter_pck_send(dst_pck);
     141             :                 }
     142         209 :                 gf_filter_pid_drop_packet(ctx->ipid);
     143         209 :                 return GF_OK;
     144             :         }
     145             : #endif //GPAC_DISABLE_AV_PARSERS
     146             : 
     147             :         return GF_NOT_SUPPORTED;
     148             : }
     149             : 
     150             : 
     151             : static const GF_FilterCapability ImgDecCaps[] =
     152             : {
     153             :         CAP_UINT(GF_CAPS_INPUT,GF_PROP_PID_STREAM_TYPE, GF_STREAM_VISUAL),
     154             :         CAP_BOOL(GF_CAPS_INPUT_EXCLUDED, GF_PROP_PID_UNFRAMED, GF_TRUE),
     155             :         CAP_UINT(GF_CAPS_INPUT,GF_PROP_PID_CODECID, GF_CODECID_JPEG),
     156             :         CAP_UINT(GF_CAPS_INPUT,GF_PROP_PID_CODECID, GF_CODECID_PNG),
     157             :         CAP_UINT(GF_CAPS_OUTPUT, GF_PROP_PID_STREAM_TYPE, GF_STREAM_VISUAL),
     158             :         CAP_UINT(GF_CAPS_OUTPUT, GF_PROP_PID_CODECID, GF_CODECID_RAW),
     159             : };
     160             : 
     161             : GF_FilterRegister ImgDecRegister = {
     162             :         .name = "imgdec",
     163             :         GF_FS_SET_DESCRIPTION("PNG/JPG decoder")
     164             :         GF_FS_SET_HELP("This filter decodes JPEG and PNG images.")
     165             :         .private_size = sizeof(GF_IMGDecCtx),
     166             :         .priority = 1,
     167             :         SETCAPS(ImgDecCaps),
     168             :         .configure_pid = imgdec_configure_pid,
     169             :         .process = imgdec_process,
     170             : };
     171             : 
     172        2877 : const GF_FilterRegister *imgdec_register(GF_FilterSession *session)
     173             : {
     174        2877 :         return &ImgDecRegister;
     175             : }

Generated by: LCOV version 1.13