Imager-File-HEIF

 view release on metacpan or  search on metacpan

HEIF.xs  view on Meta::CPAN

                hv_stores(param_hv, "default", newSVsv(boolSV(def)));
        }
        break;

    case heif_encoder_parameter_type_string:
        {
            const char * const *valid_strs = NULL;
            char value[100];
            hv_stores(param_hv, "type", newSVpvs("string"));
            err = heif_encoder_parameter_get_valid_string_values(param, &valid_strs);
            if (err.code == heif_error_Ok && valid_strs) {
                AV *values_av = newAV();
                while (*valid_strs) {
                    av_push(values_av, newSVpv(*valid_strs, 0));
                    ++valid_strs;
                }
                hv_stores(param_hv, "values", newRV_noinc((SV*)values_av));
            }
            err = heif_encoder_get_parameter_string(enc, name, value, sizeof(value));
            if (err.code == heif_error_Ok)
                hv_stores(param_hv, "default", newSVpv(value, 0));
        }
        break;

    default:
        hv_stores(param_hv, "type", newSVpvs("unknown"));
        break;
    }

    return param_hv;
}

#define MAX_ENCODERS 20

MODULE = Imager::File::HEIF  PACKAGE = Imager::File::HEIF

TYPEMAP: <<HERE
enum heif_compression_format T_COMP_FORMAT

INPUT
T_COMP_FORMAT
    $var = xi_heif_compression_format(aTHX_ SvPV_nolen($arg));

HERE

PROTOTYPES: DISABLE

Imager::ImgRaw
i_readheif(ig, page=0)
        Imager::IO     ig
               int     page
  C_ARGS: ig, page, max_threads(aTHX)

void
i_readheif_multi(ig)
        Imager::IO     ig
      PREINIT:
        i_img **imgs;
        int count;
        int i;
      PPCODE:
        imgs = i_readheif_multi(ig, &count, max_threads(aTHX));
        if (imgs) {
          EXTEND(SP, count);
          for (i = 0; i < count; ++i) {
            SV *sv = sv_newmortal();
            sv_setref_pv(sv, "Imager::ImgRaw", (void *)imgs[i]);
            PUSHs(sv);
          }
          myfree(imgs);
        }


undef_int
i_writeheif(im, ig)
    Imager::ImgRaw     im
        Imager::IO     ig

undef_int
i_writeheif_multi(ig, ...)
        Imager::IO     ig
      PREINIT:
        int i;
        int img_count;
        i_img **imgs;
      CODE:
        if (items < 2)
          croak("Usage: i_writeheif_multi(ig, images...)");
        img_count = items - 1;
        RETVAL = 1;
	if (img_count < 1) {
	  RETVAL = 0;
	  i_clear_error();
	  i_push_error(0, "You need to specify images to save");
	}
	else {
          imgs = mymalloc(sizeof(i_img *) * img_count);
          for (i = 0; i < img_count; ++i) {
	    SV *sv = ST(1+i);
	    imgs[i] = NULL;
	    if (SvROK(sv) && sv_derived_from(sv, "Imager::ImgRaw")) {
	      imgs[i] = INT2PTR(i_img *, SvIV((SV*)SvRV(sv)));
	    }
	    else {
	      i_clear_error();
	      i_push_error(0, "Only images can be saved");
              myfree(imgs);
	      RETVAL = 0;
	      break;
            }
	  }
          if (RETVAL) {
	    RETVAL = i_writeheif_multi(ig, imgs, img_count);
          }
	  myfree(imgs);
	}
      OUTPUT:
        RETVAL


MODULE = Imager::File::HEIF  PACKAGE = Imager::File::HEIF PREFIX = i_heif_

void
i_heif_dump_encoders(class)
          C_ARGS:

void
i_heif_dump_decoders(class)
          C_ARGS:

bool
i_heif_have_decoder_for(class, enum heif_compression_format fmt)
  CODE:
    if (fmt == heif_compression_undefined)
      croak("can't decode undefined");
#if !LIBHEIF_HAVE_VERSION(1, 13, 0)
    /* when testing 1.12.x and earlier couldn't decode the
       AVIFs it created
    */
    if (fmt == heif_compression_AV1)
       XSRETURN_NO;
#endif
    RETVAL = heif_have_decoder_for_format(fmt);
  OUTPUT: RETVAL

bool
i_heif_have_encoder_for(class, enum heif_compression_format fmt)
  PREINIT:
    const struct heif_encoder_descriptor *descs[MAX_ENCODERS];
    int count;
#if !LIBHEIF_HAVE_VERSION(1, 15, 0)
    struct heif_context *ctx = heif_context_alloc();
#endif
  CODE:
    if (fmt == heif_compression_undefined)
      croak("can't encode undefined");
#if LIBHEIF_HAVE_VERSION(1, 15, 0)
    count = heif_get_encoder_descriptors(fmt, NULL, descs, MAX_ENCODERS);
#else
    count = heif_context_get_encoder_descriptors(ctx, fmt, NULL, descs, MAX_ENCODERS);
    heif_context_free(ctx);
#endif
    RETVAL = count != 0;
  OUTPUT: RETVAL

void
i_heif_compression_names(class)
  PREINIT:
    size_t count;
    struct compression_names_t const *names =
        i_heif_compression_names(&count);
    size_t i;
  PPCODE:
    EXTEND(SP, count);
    /* 0 is "undefined" */
    for (i = 1; i < count; ++i)
      PUSHs(sv_2mortal(newSVpv(names[i].name, 0)));

const char *
i_heif_libversion(class)
          C_ARGS:

const char *
i_heif_buildversion(class)
          C_ARGS:

void
i_heif_init(class)
          C_ARGS:

void
i_heif_deinit(class)
          C_ARGS:

void
i_heif_encoders(class, enum heif_compression_format fmt = heif_compression_undefined)
  PREINIT:
    const struct heif_encoder_descriptor *descs[MAX_ENCODERS];
    int count;
    int i;
    struct heif_context *ctx = heif_context_alloc();
    HV *enc_stash = gv_stashpv("Imager::File::HEIF::Encoder", TRUE);
    HV *param_stash = gv_stashpv("Imager::File::HEIF::Encoder::Parameter", TRUE);
  PPCODE:
#if LIBHEIF_HAVE_VERSION(1, 15, 0)
    count = heif_get_encoder_descriptors(fmt, NULL, descs, MAX_ENCODERS);
#else
    count = heif_context_get_encoder_descriptors(ctx, fmt, NULL, descs, MAX_ENCODERS);
#endif
    EXTEND(SP, count);
    for (i = 0; i < count; ++i) {
        struct heif_error err;
        struct heif_encoder *enc = NULL;
        const struct heif_encoder_descriptor *desc = descs[i];
        HV *enchv = newHV();
        hv_stores(enchv, "id", newSVpv(heif_encoder_descriptor_get_id_name(desc), 0));
        hv_stores(enchv, "name", newSVpv(heif_encoder_descriptor_get_name(desc), 0));
        hv_stores(enchv, "compression", newSVpv(i_heif_compression_name(heif_encoder_descriptor_get_compression_format(desc)), 0));
        hv_stores(enchv, "supports_lossy_compression", newSVsv(boolSV(heif_encoder_descriptor_supports_lossy_compression(desc))));
        hv_stores(enchv, "supports_lossless_compression", newSVsv(boolSV(heif_encoder_descriptor_supports_lossless_compression(desc))));
        err = heif_context_get_encoder(ctx, desc, &enc);
        if (err.code == heif_error_Ok) {
            const struct heif_encoder_parameter * const *params =
                heif_encoder_list_parameters(enc);
            AV *param_av = newAV();
            while (*params) {
                av_push(param_av, sv_bless(newRV_noinc((SV*)make_param_hv(aTHX_ enc, *params)), param_stash));
                ++params;
            }
            hv_stores(enchv, "parameters", newRV_noinc((SV*)param_av));
            heif_encoder_release(enc);
        }
        else {
            hv_stores(enchv, "error", newSVpv(err.message, 0));
        }
        PUSHs(sv_2mortal(sv_bless(newRV_noinc((SV*)enchv), enc_stash)));
    }
    heif_context_free(ctx);

BOOT:
	PERL_INITIALIZE_IMAGER_CALLBACKS;
        i_heif_init();



( run in 0.815 second using v1.01-cache-2.11-cpan-5511b514fd6 )