コード例 #1
0
ファイル: opendcp_xml.c プロジェクト: eugen-kugler/OpenDCP
int write_volumeindex(opendcp_t *opendcp) {
    xmlIndentTreeOutput = 1;
    xmlDocPtr        doc;
    xmlTextWriterPtr xml;
    int              rc;

    dcp_log(LOG_INFO,"Writing VOLINDEX file %.256s",opendcp->volindex.filename);

    /* create XML document */
    xml = xmlNewTextWriterDoc(&doc,0);

    /* volumeindex XML Start */
    rc = xmlTextWriterStartDocument(xml, NULL, XML_ENCODING, NULL);
    if (rc < 0) {
        dcp_log(LOG_ERROR,"xmlTextWriterStartDocument failed");
        return DCP_FATAL;
    }

    xmlTextWriterStartElement(xml, BAD_CAST "VolumeIndex");
    xmlTextWriterWriteAttribute(xml, BAD_CAST "xmlns", BAD_CAST NS_AM[opendcp->ns]);
    xmlTextWriterWriteFormatElement(xml, BAD_CAST "Index","%d",1);
    xmlTextWriterEndElement(xml); 

    rc = xmlTextWriterEndDocument(xml);
    if (rc < 0) {
        dcp_log(LOG_ERROR,"xmlTextWriterEndDocument failed %s",opendcp->volindex.filename);
        return DCP_FATAL;
    }

    xmlFreeTextWriter(xml);
    xmlSaveFormatFile(opendcp->volindex.filename, doc, 1);
    xmlFreeDoc(doc);

    return DCP_SUCCESS;
}
コード例 #2
0
ファイル: opendcp_xml_sign.c プロジェクト: cbsrobot/OpenDCP
int xmlsec_init() {
    /* init libxml lib */
    xmlInitParser();
    xmlIndentTreeOutput = 1; 
    LIBXML_TEST_VERSION
    xmlLoadExtDtdDefaultValue = XML_DETECT_IDS | XML_COMPLETE_ATTRS;
    xmlSubstituteEntitiesDefault(1);

    /* init xmlsec lib */
    if(xmlSecInit() < 0) {
        dcp_log(OPENDCP_ERROR,"Error: xmlsec initialization failed.");
        return(OPENDCP_ERROR);
    }

    /* Check loaded library version */
    if(xmlSecCheckVersion() != 1) {
        dcp_log(OPENDCP_ERROR, "Error: loaded xmlsec library version is not compatible.");
        return(OPENDCP_ERROR);
    }

    /* Init crypto library */
    if(xmlSecCryptoAppInit(NULL) < 0) {
        dcp_log(OPENDCP_ERROR, "Error: crypto initialization failed.");
        return(OPENDCP_ERROR);
    }

    /* Init xmlsec-crypto library */
    if(xmlSecCryptoInit() < 0) {
        dcp_log(OPENDCP_ERROR, "Error: xmlsec-crypto initialization failed.");
        return(OPENDCP_ERROR);
    }

    return(OPENDCP_NO_ERROR);
}
コード例 #3
0
ファイル: opendcp_xml_verify.c プロジェクト: cbsrobot/OpenDCP
int xmlsec_verify_init() {
    /* init libxml lib */
    xmlInitParser();
    xmlIndentTreeOutput = 1; 
    LIBXML_TEST_VERSION
    xmlLoadExtDtdDefaultValue = XML_DETECT_IDS | XML_COMPLETE_ATTRS;
    xmlSubstituteEntitiesDefault(1);

    /* init xmlsec lib */
    if(xmlSecInit() < 0) {
        dcp_log(DCP_FATAL,"xmlsec initialization failed");
        return(DCP_FATAL);
    }

    /* Check loaded library version */
    if(xmlSecCheckVersion() != 1) {
        dcp_log(DCP_FATAL, "loaded xmlsec library version is not compatible");
        return(DCP_FATAL);
    }

    /* Init crypto library */
    if(xmlSecCryptoAppInit(NULL) < 0) {
        dcp_log(DCP_FATAL, "crypto initialization failed");
        return(DCP_FATAL);
    }

    /* Init xmlsec-crypto library */
    if(xmlSecCryptoInit() < 0) {
        dcp_log(DCP_FATAL, "xmlsec-crypto initialization failed");
        return(DCP_FATAL);
    }

    return(DCP_SUCCESS);
}
コード例 #4
0
ファイル: opendcp_common.c プロジェクト: wolfgangw/OpenDCP
int validate_reel(opendcp_t *opendcp, cpl_t *cpl, int reel) {
    int d = 0;
    int x,a;
    int picture = 0;
    int duration_mismatch = 0;

    dcp_log(LOG_INFO,"Validating Reel %d\n",reel+1);

    a = cpl->reel[reel].asset_count; 

    /* check if reel has a picture track */ 
    for (x=0;x<a;x++) {
        if (cpl->reel[reel].asset[x].essence_class == ACT_PICTURE) {
            picture++;
        }
    }

    if (picture < 1) {
        dcp_log(LOG_ERROR,"Reel %d has no picture track",reel);
        return DCP_NO_PICTURE_TRACK;
    } else if (picture > 1) {
        dcp_log(LOG_ERROR,"Reel %d has multiple picture tracks",reel);
        return DCP_MULTIPLE_PICTURE_TRACK;
    }

    d = cpl->reel[reel].asset[0].duration;

    /* check durations */
    for (x=0;x<a;x++) {
        if (cpl->reel[reel].asset[x].duration) {
            if (cpl->reel[reel].asset[x].duration != d) {
                duration_mismatch = 1;
                if (cpl->reel[reel].asset[x].duration < d) {
                   d = cpl->reel[reel].asset[x].duration;
                }
            }
        } else {
            dcp_log(LOG_ERROR,"Asset %s has no duration",cpl->reel[reel].asset[x].filename);
           return DCP_ASSET_NO_DURATION;
        }
    }

    if (duration_mismatch) {
       dcp_log(LOG_WARN,"Asset duration mismatch, adjusting all durations to shortest asset duration of %d frames", d);
        for (x=0;x<a;x++) {
            cpl->reel[reel].asset[x].duration = d;
        }
    }
          
    return DCP_SUCCESS;
}
コード例 #5
0
ファイル: opendcp_cli.c プロジェクト: eugen-kugler/OpenDCP
int build_filelist(char *input, char *output, filelist_t *filelist, int file_type) {
    struct dirent **files;
    int x = 0;
    struct stat st_in;

    if (stat(input, &st_in) != 0 ) {
        dcp_log(LOG_ERROR,"Could not open input file %s",input);
        return DCP_FATAL;
    }

    filelist->file_count = scandir(input,&files,(void *)file_filter,alphasort);
    if (filelist->file_count) {
        for (x=0;x<filelist->file_count;x++) {
            sprintf(filelist->in[x],"%s/%s",input,files[x]->d_name);
            if (file_type == J2K_INPUT) {
                sprintf(filelist->out[x],"%s/%s.j2c",output,get_basename(files[x]->d_name));
            }
        }
     }
    for (x=0;x<filelist->file_count;x++) {
        free(files[x]);
    }
    free(files);

    return DCP_SUCCESS;
}
コード例 #6
0
ファイル: opendcp_cli.c プロジェクト: eugen-kugler/OpenDCP
int get_file_count(char *path, int file_type) {
    struct dirent **files;
    struct stat st_in;

    int x,count;

    filter = file_type;

    if (stat(path, &st_in) != 0 ) {
        dcp_log(LOG_ERROR,"Could not open input file %s",path);
        return DCP_FATAL;
    }

    if (S_ISDIR(st_in.st_mode)) {
        count = scandir(path,&files,(void *)file_filter,alphasort);
        for (x=0;x<count;x++) {
            free(files[x]);
        }
        free(files);

    } else {
        count = 1;
    }

    return count;
}
コード例 #7
0
ファイル: opendcp_j2k.c プロジェクト: kzbb/OpenDCP
/* convert opendcp to openjpeg image format */
int odcp_to_opj(odcp_image_t *odcp, opj_image_t **opj_ptr) {
    OPJ_COLOR_SPACE color_space;
    opj_image_cmptparm_t cmptparm[3];
    opj_image_t *opj = NULL;
    int j,size;

    color_space = CLRSPC_SRGB;

    /* initialize image components */
    memset(&cmptparm[0], 0, odcp->n_components * sizeof(opj_image_cmptparm_t));
    for (j = 0;j <  odcp->n_components;j++) {
            cmptparm[j].w = odcp->w;
            cmptparm[j].h = odcp->h;
            cmptparm[j].prec = odcp->precision;
            cmptparm[j].bpp = odcp->bpp;
            cmptparm[j].sgnd = odcp->signed_bit;
            cmptparm[j].dx = odcp->dx;
            cmptparm[j].dy = odcp->dy;
    }

    /* create the image */
    opj = opj_image_create(odcp->n_components, &cmptparm[0], color_space);

    if(!opj) {
        dcp_log(LOG_ERROR,"Failed to create image");
        return OPENDCP_ERROR;
    }

    /* set image offset and reference grid */
    opj->x0 = odcp->x0;
    opj->y0 = odcp->y0;
    opj->x1 = odcp->x1;
    opj->y1 = odcp->y1;

    size = odcp->w * odcp->h;

    memcpy(opj->comps[0].data,odcp->component[0].data,size*sizeof(int));
    memcpy(opj->comps[1].data,odcp->component[1].data,size*sizeof(int));
    memcpy(opj->comps[2].data,odcp->component[2].data,size*sizeof(int));

    *opj_ptr = opj;
    return OPENDCP_NO_ERROR;
}
コード例 #8
0
ファイル: opendcp_xml_verify.c プロジェクト: cbsrobot/OpenDCP
int xml_verify(char *filename) {
    xmlSecDSigCtxPtr dsig_ctx = NULL;
    xmlDocPtr        doc = NULL;
    xmlNodePtr       root_node;
    xmlNodePtr       sign_node;
    xmlNodePtr       cert_node;
    xmlNodePtr       x509d_node; 
    xmlNodePtr       cur_node; 
    int              result = DCP_FATAL;
    xmlSecKeysMngrPtr key_manager;
    char cert[5000];
    int  cert_l; 
    xmlsec_verify_init();

    /* load doc file */
    doc = xmlParseFile(filename);

    if (doc == NULL) {
        dcp_log(LOG_ERROR, "unable to parse file %s", filename);
        goto done;
    }

    /* find root node */
    root_node = xmlDocGetRootElement(doc);

    if (root_node == NULL){
        dcp_log(LOG_ERROR, "unable to find root node");
        goto done;
    }

    /* find signature node */
    sign_node = xmlSecFindNode(root_node, xmlSecNodeSignature, xmlSecDSigNs);
    if(sign_node == NULL) {
        dcp_log(LOG_ERROR, "signature node not found");
        goto done;      
    }

    /* create keys manager */
    key_manager = load_certificates();
    if (key_manager == NULL) {
        dcp_log(LOG_ERROR,"create key manager failed");
        goto done;
    }

    /* find certificates */
    cur_node = sign_node;
    while (x509d_node = xmlSecFindNode(cur_node, xmlSecNodeX509Data, xmlSecDSigNs)) {
        cert_node = xmlSecFindNode(x509d_node, xmlSecNodeX509Certificate, xmlSecDSigNs);
        if(cert_node == NULL) {
            dcp_log(LOG_ERROR, "X509certficate node not found");
            goto done;      
        }
        sprintf(cert,"-----BEGIN CERTIFICATE-----\n%s\n-----END CERTIFICATE-----\n",xmlNodeGetContent(cert_node));
        cert_l = strlen(cert);
        if (xmlSecCryptoAppKeysMngrCertLoadMemory(key_manager, cert, cert_l, xmlSecKeyDataFormatPem, xmlSecKeyDataTypeTrusted) < 0) {
            dcp_log(LOG_ERROR, "could read X509certificate node value");
            goto done;      
        }
        cur_node = xmlNextElementSibling(x509d_node);
    }

    /* create signature context */
    dsig_ctx = xmlSecDSigCtxCreate(key_manager);

    if (dsig_ctx == NULL) {
        dcp_log(LOG_ERROR,"create signature opendcp failed");
        goto done;
    }

    /* sign the template */
    if (xmlSecDSigCtxVerify(dsig_ctx, sign_node) < 0) {
        dcp_log(LOG_ERROR,"signature verify failed");
        goto done;
    }

    if (dsig_ctx->status != xmlSecDSigStatusSucceeded) {
        dcp_log(LOG_ERROR,"signature validation failed");
        goto done;
    }

    /* success */
    result = 0;

done:    
    /* destroy keys manager */
    xmlSecKeysMngrDestroy(key_manager);

    /* destroy signature context */
    if(dsig_ctx != NULL) {
        xmlSecDSigCtxDestroy(dsig_ctx);
    }
    
    /* destroy xml doc */
    if(doc != NULL) {
        xmlFreeDoc(doc); 
    }

    xmlsec_close();
    return(result);
}
コード例 #9
0
ファイル: opendcp_xml_sign.c プロジェクト: cbsrobot/OpenDCP
int write_dsig_template(opendcp_t *opendcp, xmlTextWriterPtr xml) {
    BIO *bio[3];
    X509 *x[3];
    X509_NAME *issuer_xn[3];
    X509_NAME *subject_xn[3];
    char *cert[3];
    int i;

    dcp_log(LOG_DEBUG, "xml_sign: write_dsig_template");

    if (opendcp->xml_signature.use_external) {
        /* read certificates from file */
        FILE *cp;

        cp = fopen(opendcp->xml_signature.signer,"rb");
        if (cp) {
            x[0] = PEM_read_X509(cp,NULL,NULL,NULL);
            fclose(cp);
        }
        cp = fopen(opendcp->xml_signature.ca,"rb");
        if (cp) {
            x[1] = PEM_read_X509(cp,NULL,NULL,NULL);
            fclose(cp);
        }
        cp = fopen(opendcp->xml_signature.root,"rb");
        if (cp) {
            x[2] = PEM_read_X509(cp,NULL,NULL,NULL);
            fclose(cp);
        }
        cert[0] = strip_cert_file(opendcp->xml_signature.signer);
        cert[1] = strip_cert_file(opendcp->xml_signature.ca);
        cert[2] = strip_cert_file(opendcp->xml_signature.root);
    } else {
        /* read certificate from memory */
        bio[0] = BIO_new_mem_buf((void *)opendcp_signer_cert, -1);
        bio[1] = BIO_new_mem_buf((void *)opendcp_ca_cert, -1);
        bio[2] = BIO_new_mem_buf((void *)opendcp_root_cert, -1);

        /* save a copy with the BEGIN/END stripped */
        cert[0] = strip_cert(opendcp_signer_cert);
        cert[1] = strip_cert(opendcp_ca_cert);
        cert[2] = strip_cert(opendcp_root_cert);

        for (i=0;i<3;i++) {
            if (bio[i] == NULL) {
                dcp_log(LOG_ERROR,"Could allocate certificate from memory");
                return OPENDCP_ERROR;
            }
            x[i] = PEM_read_bio_X509(bio[i], NULL, NULL, NULL);

            if (!BIO_set_close(bio[i], BIO_NOCLOSE)) {
                dcp_log(LOG_ERROR,"Could set BIO close flag");
                return OPENDCP_ERROR;
            }

            if (x[i] == NULL) {
                dcp_log(LOG_ERROR,"Could not read certificate");
                return OPENDCP_ERROR;
             }
        }
    }

    /* get issuer, subject */
    for (i=0;i<3;i++) {
        issuer_xn[i]  =  X509_get_issuer_name(x[i]);
        subject_xn[i] =  X509_get_subject_name(x[i]);
        if (issuer_xn[i] == NULL || subject_xn[i] == NULL) {
            dcp_log(LOG_ERROR,"Could not parse certificate data");
            return OPENDCP_ERROR;
        }
    }

    dcp_log(LOG_DEBUG, "xml_sign: write_dsig_template: start signer");

    /* signer */
    xmlTextWriterStartElement(xml, BAD_CAST "Signer");
    xmlTextWriterStartElementNS(xml, BAD_CAST "dsig",
                                BAD_CAST "X509Data", NULL);

    xmlTextWriterStartElementNS(xml, BAD_CAST "dsig",
                                BAD_CAST "X509IssuerSerial", NULL);

    xmlTextWriterWriteFormatElementNS(xml, BAD_CAST "dsig",
                                      BAD_CAST "X509IssuerName", NULL, "%s",
                                      dn_oneline(issuer_xn[0]));

    xmlTextWriterWriteFormatElementNS(xml, BAD_CAST "dsig",
                                      BAD_CAST "X509SerialNumber", NULL, "%ld",
                                      ASN1_INTEGER_get(X509_get_serialNumber(x[0])));
    xmlTextWriterEndElement(xml);

    xmlTextWriterWriteFormatElementNS(xml, BAD_CAST "dsig",
                                      BAD_CAST "X509SubjectName", NULL,
                                     "%s", dn_oneline(subject_xn[0]));

    xmlTextWriterEndElement(xml);
    xmlTextWriterEndElement(xml);

    /* template */
    xmlTextWriterStartElementNS(xml, BAD_CAST "dsig",
                                BAD_CAST "Signature", NULL);

    xmlTextWriterStartElementNS(xml, BAD_CAST "dsig",
                                BAD_CAST "SignedInfo", NULL);

    xmlTextWriterStartElementNS(xml, BAD_CAST "dsig",
                                BAD_CAST "CanonicalizationMethod", NULL);

    xmlTextWriterWriteAttribute(xml, BAD_CAST "Algorithm",
                                BAD_CAST DS_CMA);

    xmlTextWriterEndElement(xml);

    xmlTextWriterStartElementNS(xml, BAD_CAST "dsig",
                                BAD_CAST "SignatureMethod", NULL);

    xmlTextWriterWriteAttribute(xml, BAD_CAST "Algorithm",
                                BAD_CAST DS_SMA[opendcp->ns]);

    xmlTextWriterEndElement(xml);

    xmlTextWriterStartElementNS(xml, BAD_CAST "dsig",
                                BAD_CAST "Reference",
                                NULL);

    xmlTextWriterWriteAttribute(xml, BAD_CAST "URI", BAD_CAST NULL);

    xmlTextWriterStartElementNS(xml, BAD_CAST "dsig",
                                BAD_CAST"Transforms",
                                NULL);

    xmlTextWriterStartElementNS(xml, BAD_CAST "dsig",
                                BAD_CAST "Transform",
                                NULL);

    xmlTextWriterWriteAttribute(xml, BAD_CAST "Algorithm",
                                BAD_CAST DS_TMA);

    xmlTextWriterEndElement(xml);
    xmlTextWriterEndElement(xml);

    xmlTextWriterStartElementNS(xml, BAD_CAST "dsig",
                                BAD_CAST "DigestMethod", NULL);

    xmlTextWriterWriteAttribute(xml, BAD_CAST "Algorithm",
                                BAD_CAST DS_DMA);

    xmlTextWriterEndElement(xml);

    xmlTextWriterWriteElementNS(xml, BAD_CAST "dsig",
                                BAD_CAST "DigestValue",
                                NULL, BAD_CAST "");

    xmlTextWriterEndElement(xml);
    xmlTextWriterEndElement(xml);

    xmlTextWriterWriteElementNS(xml, BAD_CAST "dsig",
                                BAD_CAST "SignatureValue",
                                NULL, BAD_CAST "");

    xmlTextWriterStartElementNS(xml, BAD_CAST "dsig",
                                BAD_CAST "KeyInfo", NULL);

    for (i=0;i<3;i++) {
        xmlTextWriterStartElementNS(xml, BAD_CAST "dsig",
                                    BAD_CAST "X509Data", NULL);
        xmlTextWriterStartElementNS(xml, BAD_CAST "dsig",
                                    BAD_CAST "X509IssuerSerial", NULL);

        xmlTextWriterWriteFormatElementNS(xml, BAD_CAST "dsig",
                                          BAD_CAST "X509IssuerName", NULL, "%s",
                                          dn_oneline(issuer_xn[i]));

        xmlTextWriterWriteFormatElementNS(xml, BAD_CAST "dsig",
                                          BAD_CAST "X509SerialNumber", NULL, "%ld",
                                          ASN1_INTEGER_get(X509_get_serialNumber(x[i])));
        xmlTextWriterEndElement(xml);

        xmlTextWriterWriteFormatElementNS(xml, BAD_CAST "dsig",
                                          BAD_CAST "X509Certificate", NULL, "%s",
                                          cert[i]);

        xmlTextWriterEndElement(xml);
    }

    xmlTextWriterEndElement(xml); /* KeyInfo */
    xmlTextWriterEndElement(xml); /* Signature */

    if (subject_xn[0]) {
       free(subject_xn[0]);
    } 

    for (i=0;i<3;i++) {
        if (issuer_xn[i]) {
            free(issuer_xn[i]);
        }
    }

    return OPENDCP_NO_ERROR;
}
コード例 #10
0
ファイル: opendcp_xml_sign.c プロジェクト: cbsrobot/OpenDCP
int xml_sign(opendcp_t *opendcp, char *filename) {
    xmlSecDSigCtxPtr dsig_ctx = NULL;
    xmlDocPtr        doc = NULL;
    xmlNodePtr       root_node;
    xmlNodePtr       sign_node;
    FILE *fp;
    int result = OPENDCP_ERROR;
    xmlSecKeysMngrPtr key_manager = NULL;
    
    dcp_log(LOG_DEBUG, "xml_sign: xmlsec_init");
    xmlsec_init();

    /* load doc file */
    dcp_log(LOG_DEBUG, "xml_sign: parse file");
    doc = xmlParseFile(filename);

    if (doc == NULL) {
        dcp_log(OPENDCP_ERROR, "Error: unable to parse file %s", filename);
        goto done;
    }

    /* find root node */
    root_node = xmlDocGetRootElement(doc);

    if (root_node == NULL){
        dcp_log(OPENDCP_ERROR, "Error: unable to find root node");
        goto done;
    }

    /* find signature node */
    sign_node = xmlSecFindNode(root_node, xmlSecNodeSignature, xmlSecDSigNs);
    if(sign_node == NULL) {
        fprintf(stderr, "Error: start node not found");
        goto done;      
    }
  
    /* create keys manager */
    key_manager = load_certificates_sign(opendcp);
    if (key_manager == NULL) {
        fprintf(stderr,"Error: failed to create key manager\n");
        goto done;
    }

    /* create signature opendcp */
    dsig_ctx = xmlSecDSigCtxCreate(key_manager);
 
    if(dsig_ctx == NULL) {
        fprintf(stderr,"Error: failed to create signature opendcp\n");
        goto done;
    }

    /* sign the template */
    if(xmlSecDSigCtxSign(dsig_ctx, sign_node) < 0) {
        fprintf(stderr,"Error: signature failed\n");
        goto done;
    }

    /* open xml file */
    fp = fopen(filename,"wb"); 

    if (fp == NULL) {
        fprintf(stderr,"Error: could not open output file\n");
        goto done;
    }

    /* write the xml file */
    if (xmlDocDump(fp, doc) < 0) {
        fprintf(stderr,"Error: writing XML document failed\n");
        goto done;
    }
  
    /* close the file */
    fclose(fp);

    /* success */
    result = 0;

done:    
    /* destroy keys manager */
    xmlSecKeysMngrDestroy(key_manager);

    /* destroy signature context */
    if(dsig_ctx != NULL) {
        xmlSecDSigCtxDestroy(dsig_ctx);
    }
    
    /* destroy xml doc */
    if(doc != NULL) {
        xmlFreeDoc(doc); 
    }

    xmlsec_close();

    return(result);
}
コード例 #11
0
ファイル: opendcp_xml_cmd.c プロジェクト: wolfgangw/OpenDCP
int main (int argc, char **argv) {
    int c,j;
    int reel_count=0;
    int height = 0;
    int width  = 0;
    char buffer[80];
    opendcp_t *opendcp;
    asset_list_t reel_list[MAX_REELS];

    if ( argc <= 1 ) {
        dcp_usage();
    }

    opendcp = create_opendcp();

    /* parse options */
    while (1)
    {
        static struct option long_options[] =
        {
            {"annotation",     required_argument, 0, 'a'},
            {"base",           required_argument, 0, 'b'},
            {"digest",         no_argument,       0, 'd'},
            {"duration",       required_argument, 0, 'n'},
            {"entry",          required_argument, 0, 'e'},
            {"help",           no_argument,       0, 'h'},
            {"issuer",         required_argument, 0, 'i'},
            {"kind",           required_argument, 0, 'k'},
            {"log_level",      required_argument, 0, 'l'},
            {"rating",         required_argument, 0, 'm'},
            {"reel",           required_argument, 0, 'r'},
            {"title",          required_argument, 0, 't'},
            {"root",           required_argument, 0, '1'},
            {"ca",             required_argument, 0, '2'},
            {"signer",         required_argument, 0, '3'},
            {"privatekey",     required_argument, 0, 'p'},
            {"sign",           no_argument,       0, 's'},
            {"height",         required_argument, 0, 'y'},
            {"width",          required_argument, 0, 'x'},
            {"version",        no_argument,       0, 'v'},
            {0, 0, 0, 0}
        };

        /* getopt_long stores the option index here. */
        int option_index = 0;
     
        c = getopt_long (argc, argv, "a:b:e:svdhi:k:r:l:m:n:t:x:y:p:1:2:3:",
                         long_options, &option_index);

        /* Detect the end of the options. */
        if (c == -1)
            break;
     
        switch (c)
        {
            case 0:
                /* If this option set a flag, do nothing else now. */
                if (long_options[option_index].flag != 0)
                   break;
            break;

            case 'a':
               sprintf(opendcp->xml.annotation,"%.128s",optarg);
            break;

            case 'b':
               sprintf(opendcp->xml.basename,"%.80s",optarg);
            break;

            case 'd':
               opendcp->xml.digest_flag = 1;
            break;

            case 'e':
               opendcp->entry_point = atoi(optarg);
            break;

            case 'h':
               dcp_usage();
            break;
     
            case 'i':
               sprintf(opendcp->xml.issuer,"%.80s",optarg);
            break;

            case 'k':
               sprintf(opendcp->xml.kind,"%.15s",optarg);
            break;

            case 'l':
               opendcp->log_level = atoi(optarg);
            break;

            case 'm':
               if ( !strcmp(optarg,"G")
                    || !strcmp(optarg,"PG")
                    || !strcmp(optarg,"PG-13")
                    || !strcmp(optarg,"R")
                    || !strcmp(optarg,"NC-17") ) {
                   sprintf(opendcp->xml.rating,"%.5s",optarg);
               } else {
                   sprintf(buffer,"Invalid rating %s\n",optarg);
                   dcp_fatal(opendcp,buffer);
               }
            break;

            case 'n':
               opendcp->duration = atoi(optarg);
            break;
     
            case 'r':
               j = 0;
               optind--;
               while ( optind<argc && strncmp("-",argv[optind],1) != 0) {
				   sprintf(reel_list[reel_count].asset_list[j++].filename,"%s",argv[optind++]);
               }
               reel_list[reel_count++].asset_count = j--;
            break;

#ifdef XMLSEC
            case 's':
                opendcp->xml_signature.sign = 1;

            break;
#endif

            case 't':
               sprintf(opendcp->xml.title,"%.80s",optarg);
            break;

            case 'x':
               width = atoi(optarg);
            break;

            case 'y':
               height = atoi(optarg);
            break;

            case '1':
               opendcp->xml_signature.root = optarg;
               opendcp->xml_signature.use_external = 1;
            break;

            case '2':
               opendcp->xml_signature.ca = optarg;
               opendcp->xml_signature.use_external = 1;
            break;

            case '3':
               opendcp->xml_signature.signer = optarg;
               opendcp->xml_signature.use_external = 1;
            break;

            case 'p':
               opendcp->xml_signature.private_key = optarg;
               opendcp->xml_signature.use_external = 1;
            break;

            case 'v':
               version();
            break;

            default:
               dcp_usage();
        }
    }

    /* set log level */
    dcp_set_log_level(opendcp->log_level);

    if (opendcp->log_level > 0) {
        printf("\nOpenDCP XML %s %s\n\n",OPENDCP_VERSION,OPENDCP_COPYRIGHT);
    }

    if (reel_count < 1) {
        dcp_fatal(opendcp,"No reels supplied");
    }

    /* check cert files */
    if (opendcp->xml_signature.sign && opendcp->xml_signature.use_external == 1) {
        FILE *tp;
        if (opendcp->xml_signature.root) {
            tp = fopen(opendcp->xml_signature.root,"rb");
            if (tp) {
                fclose(tp);
            } else {
                dcp_fatal(opendcp,"Could not read root certificate");
            }
        } else {
            dcp_fatal(opendcp,"XML digital signature certifcates enabled, but root certificate file not specified");
        }
        if (opendcp->xml_signature.ca) {
            tp = fopen(opendcp->xml_signature.ca,"rb");
            if (tp) {
                fclose(tp);
            } else {
                dcp_fatal(opendcp,"Could not read ca certificate");
            }
        } else {
            dcp_fatal(opendcp,"XML digital signature certifcates enabled, but ca certificate file not specified");
        }
        if (opendcp->xml_signature.signer) {
            tp = fopen(opendcp->xml_signature.signer,"rb");
            if (tp) {
                fclose(tp);
            } else {
                dcp_fatal(opendcp,"Could not read signer certificate");
            }
        } else {
            dcp_fatal(opendcp,"XML digital signature certifcates enabled, but signer certificate file not specified");
        }
        if (opendcp->xml_signature.private_key) {
            tp = fopen(opendcp->xml_signature.private_key,"rb");
            if (tp) {
                fclose(tp);
            } else {
                dcp_fatal(opendcp,"Could not read private key file");
            }
        } else {
            dcp_fatal(opendcp,"XML digital signature certifcates enabled, but private key file not specified");
        }
    }
  
    /* set aspect ratio override */
    if (width || height) {
        if (!height) {
            dcp_fatal(opendcp,"You must specify height, if you specify width");
        }

        if (!width) {
            dcp_fatal(opendcp,"You must specify widht, if you specify height");
        }

        sprintf(opendcp->xml.aspect_ratio,"%d %d",width,height);
    }

    /* add pkl to the DCP (only one PKL currently support) */
    add_pkl(opendcp);

    /* add cpl to the DCP/PKL (only one CPL currently support) */
    add_cpl(opendcp, &opendcp->pkl[0]);

    /* Add and validate reels */
    for (c = 0;c<reel_count;c++) {
        if (add_reel(opendcp, &opendcp->pkl[0].cpl[0], reel_list[c]) != DCP_SUCCESS) {
            sprintf(buffer,"Could not add reel %d to DCP\n",c+1); 
            dcp_fatal(opendcp,buffer);
        }
       if (validate_reel(opendcp, &opendcp->pkl[0].cpl[0], c) != DCP_SUCCESS) {
            sprintf(buffer,"Could validate reel %d\n",c+1); 
            dcp_fatal(opendcp,buffer);
       }
    }

    /* set ASSETMAP/VOLINDEX path */
    if (opendcp->ns == XML_NS_SMPTE) {
        sprintf(opendcp->assetmap.filename,"%s","ASSETMAP.xml");
        sprintf(opendcp->volindex.filename,"%s","VOLINDEX.xml");
    } else {
        sprintf(opendcp->assetmap.filename,"%s","ASSETMAP");
        sprintf(opendcp->volindex.filename,"%s","VOLINDEX");
    }

    /* Write XML Files */
    if (write_cpl(opendcp, &opendcp->pkl[0].cpl[0]) != DCP_SUCCESS)
        dcp_fatal(opendcp,"Writing composition playlist failed");
    if (write_pkl(opendcp, &opendcp->pkl[0]) != DCP_SUCCESS)
        dcp_fatal(opendcp,"Writing packing list failed");
    if (write_volumeindex(opendcp) != DCP_SUCCESS)
        dcp_fatal(opendcp,"Writing volume index failed");
    if (write_assetmap(opendcp) != DCP_SUCCESS)
        dcp_fatal(opendcp,"Writing asset map failed");

    dcp_log(LOG_INFO,"DCP Complete");

    if (opendcp->log_level > 0) {
        printf("\n");
    }

    delete_opendcp(opendcp);

    exit(0);
}
コード例 #12
0
void print_bmp_header(bmp_image_t *bmp) {
    dcp_log(LOG_DEBUG,"%-15.15s: file size:    %d","read_bmp",bmp->file.size);
    dcp_log(LOG_DEBUG,"%-15.15s: data offset:  %d","read_bmp",bmp->file.offset);

    dcp_log(LOG_DEBUG,"%-15.15s: header_size:  %d","read_bmp",bmp->image.header_size);
    dcp_log(LOG_DEBUG,"%-15.15s: width:        %d","read_bmp",bmp->image.width);
    dcp_log(LOG_DEBUG,"%-15.15s: height:       %d","read_bmp",bmp->image.height);
    dcp_log(LOG_DEBUG,"%-15.15s: planes:       %d","read_bmp",bmp->image.planes);
    dcp_log(LOG_DEBUG,"%-15.15s: bpp:          %d","read_bmp",bmp->image.bpp);
    dcp_log(LOG_DEBUG,"%-15.15s: compression:  %d","read_bmp",bmp->image.compression);
    dcp_log(LOG_DEBUG,"%-15.15s: size:         %d","read_bmp",bmp->image.image_size);
    dcp_log(LOG_DEBUG,"%-15.15s: x:            %d","read_bmp",bmp->image.x_ppm);
    dcp_log(LOG_DEBUG,"%-15.15s: y:            %d","read_bmp",bmp->image.y_ppm);
    dcp_log(LOG_DEBUG,"%-15.15s: colors_used:  %d","read_bmp",bmp->image.colors_used);
    dcp_log(LOG_DEBUG,"%-15.15s: colors_impor: %d","read_bmp",bmp->image.colors_important);

    dcp_log(LOG_DEBUG,"%-15.15s: row_order:    %d","read_bmp",bmp->row_order);
}
コード例 #13
0
int opendcp_decode_bmp(odcp_image_t **image_ptr, const char *infile) {
    bmp_magic_num_t magic;
    bmp_image_t     bmp;
    FILE            *bmp_fp;
    odcp_image_t    *image = 00;
    int             pixels = 0;
    int             i,w,h;
    size_t          readsize;

    /* open bmp using filename or file descriptor */
    dcp_log(LOG_DEBUG,"%-15.15s: opening bmp file %s","read_bmp",infile);

    bmp_fp = fopen(infile, "rb");

    if (!bmp_fp) {
        dcp_log(LOG_ERROR,"%-15.15s: opening bmp file %s","read_bmp",infile);
        return OPENDCP_FATAL;
    }

    readsize = fread(&magic, 1, sizeof(bmp_magic_num_t), bmp_fp);
    if (readsize != sizeof(bmp_magic_num_t)) {
        dcp_log(LOG_ERROR,"%-15.15s: failed to read magic number expected %d read %d","read_bmp", sizeof(bmp_magic_num_t), readsize);
    }

    readsize = fread(&bmp, 1, sizeof(bmp_image_t), bmp_fp);
    if (readsize != sizeof(bmp_image_t)) {
        dcp_log(LOG_ERROR,"%-15.15s: failed to header expected %d read %d","read_bmp", sizeof(bmp_image_t), readsize);
    }

    if (magic.magic_num != MAGIC_NUMBER) {
         dcp_log(LOG_ERROR,"%s is not a valid BMP file", infile);
    }

    if (bmp.image.height < 0) {
        bmp.row_order = BMP_TOP;
    } else {
        bmp.row_order = BMP_BOTTOM;
    }

    w = bmp.image.width;
    h = abs(bmp.image.height);
    pixels = w * h;

    print_bmp_header(&bmp);

    switch (bmp.image.compression) {
        case BMP_RGB:
            break;
        case BMP_RLE8:
        case BMP_RLE4:
        case BMP_BITFIELDS:
        case BMP_JPEG:
        case BMP_PNG:
        default:
            dcp_log(LOG_ERROR, "Unsupported image compression: %d", bmp.image.compression);
            return OPENDCP_FATAL;
            break;
    }

    /* apparently, some applications don't fill in the image size */
    if (bmp.image.image_size == 0) {
        dcp_log(LOG_WARN, "BMP missing file size field, will attempt to calculate");
        bmp.image.image_size = bmp.file.size - sizeof(bmp_magic_num_t) - sizeof(bmp_image_t);
    }

    if (bmp.image.bpp < 24 || bmp.image.bpp > 32) {
        dcp_log(LOG_ERROR, "%d-bit depth is not supported.",bmp.image.bpp);
        return OPENDCP_FATAL;
    }

    /* create the image */
    dcp_log(LOG_DEBUG,"%-15.15s: allocating odcp image","read_bmp");
    image = odcp_image_create(3, w, h);
    dcp_log(LOG_DEBUG,"%-15.15s: image allocated","read_bmp");

    int row_size = ((bmp.image.bpp * w + 31) / 32) * 4;
    dcp_log(LOG_DEBUG, "%-15,15s: row size %d data size %d", "read_bmp", row_size, sizeof(uint8_t));

    fseek(bmp_fp, bmp.file.offset, SEEK_SET);

    /* RGB(A) */
    if (bmp.image.compression == BMP_RGB) {
        /* 16-bits per pixel */
        if (bmp.image.bpp == 16 ) {
            uint8_t data[2];
            for (i=0; i<pixels; i++) {
                fread(&data,sizeof(data),1,bmp_fp);
                int p = invert_row(bmp, i);
                image->component[BMP_B].data[p] = data[0] << 2;
                image->component[BMP_G].data[p] = data[0] << 4;
                image->component[BMP_R].data[p] = data[1] << 2;
            }
        /* 24-bits per pixel */
        } else if (bmp.image.bpp == 24 ) {
            uint8_t data[3];
            for (i=0; i<pixels; i++) {
                fread(&data, sizeof(uint8_t), sizeof(data), bmp_fp);
                int p = invert_row(bmp, i);
                image->component[BMP_B].data[p] = data[0] << 4;
                image->component[BMP_G].data[p] = data[1] << 4;
                image->component[BMP_R].data[p] = data[2] << 4;;
            }
        /* 32-bits per pixel */
        } else if (bmp.image.bpp == 32 ) {
            uint8_t data[4];
            for (i=0; i<pixels; i++) {
                fread(&data, sizeof(uint8_t), sizeof(data), bmp_fp);
                int p = invert_row(bmp, i);
                image->component[BMP_B].data[p] = data[0] << 4;
                image->component[BMP_G].data[p] = data[1] << 4;
                image->component[BMP_R].data[p] = data[2] << 4;
            }
        }
    }
    /* RGB(A) */

    fclose(bmp_fp);

    dcp_log(LOG_DEBUG,"%-15.15s: BMP read complete","read_bmp");
    *image_ptr = image;

    return OPENDCP_NO_ERROR;
}
コード例 #14
0
ファイル: opendcp_common.c プロジェクト: wolfgangw/OpenDCP
void dcp_fatal(opendcp_t *opendcp, char *error) {
    dcp_log(LOG_ERROR, "%s",error);
    exit(DCP_FATAL);
}
コード例 #15
0
ファイル: opendcp_common.c プロジェクト: wolfgangw/OpenDCP
int add_reel(opendcp_t *opendcp, cpl_t *cpl, asset_list_t reel) {
    int result;
    int x,r;
    FILE *fp;
    char *filename;
    asset_t asset;
    struct stat st;
    char uuid_s[40];

    dcp_log(LOG_INFO,"Adding Reel");

    r = cpl->reel_count; 

    /* add reel uuid */
    uuid_random(uuid_s);
    sprintf(cpl->reel[r].uuid,"%.36s",uuid_s);

    /* parse argument and read asset information */
    for (x=0;x<reel.asset_count;x++) {
        filename=reel.asset_list[x].filename;
        init_asset(&asset);
      
        sprintf(asset.filename,"%s",filename);
        sprintf(asset.annotation,"%s",basename(filename));

        /* check if file exists */
        if ((fp = fopen(filename, "r")) == NULL) {
            dcp_log(LOG_ERROR,"add_reel: Could not open file: %s",filename);
            return DCP_FILE_OPEN_ERROR;
        } else {
            fclose (fp);
        }

        /* get file size */
        stat(filename, &st);
        sprintf(asset.size,"%"PRIu64, st.st_size);

        /* read asset information */
        dcp_log(LOG_INFO,"add_reel: Reading %s asset information",filename);

        result = read_asset_info(&asset);

        if (result == DCP_FATAL) {
            dcp_log(LOG_ERROR,"%s is not a proper essence file",filename);
            return DCP_INVALID_ESSENCE;
        }

        if (x == 0) {
            opendcp->ns = asset.xml_ns;
            dcp_log(LOG_DEBUG,"add_reel: Label type detected: %d",opendcp->ns);
        } else {
            if (opendcp->ns != asset.xml_ns) {
                dcp_log(LOG_ERROR,"Warning DCP specification mismatch in assets. Please make sure all assets are MXF Interop or SMPTE");
                return DCP_SPECIFCATION_MISMATCH;
            }
        }

        /* force aspect ratio, if specified */
        if (strcmp(opendcp->xml.aspect_ratio,"") ) {
            sprintf(asset.aspect_ratio,"%s",opendcp->xml.aspect_ratio);
        }

        /* Set duration, if specified */
        if (opendcp->duration) {
            if  (opendcp->duration<asset.duration) {
                asset.duration = opendcp->duration;
            } else {
                dcp_log(LOG_WARN,"Desired duration %d cannot be greater than assset duration %d, ignoring value",opendcp->duration,asset.duration);
            }
        }

        /* Set entry point, if specified */
        if (opendcp->entry_point) {
            if (opendcp->entry_point<asset.duration) {
                asset.entry_point = opendcp->entry_point;
            } else {
                dcp_log(LOG_WARN,"Desired entry point %d cannot be greater than assset duration %d, ignoring value",opendcp->entry_point,asset.duration);
            }
        }

        /* calculate digest */
        calculate_digest(filename,asset.digest);
   
        /* get asset type */
        result = get_asset_type(asset);

        /* add asset to cpl */
        cpl->reel[r].asset[x] = asset;
        cpl->reel[r].asset_count++;
    }

    cpl->reel_count++;

    return DCP_SUCCESS;
}
コード例 #16
0
ファイル: opendcp_xml.c プロジェクト: eugen-kugler/OpenDCP
int write_cpl(opendcp_t *opendcp, cpl_t *cpl) {
    int a,r, rc;
    struct stat st;
    xmlIndentTreeOutput = 1;
    xmlDocPtr        doc; 
    xmlTextWriterPtr xml;

    /* create XML document */
    xml = xmlNewTextWriterDoc(&doc,0);

    /* cpl start */
    rc = xmlTextWriterStartDocument(xml, NULL, XML_ENCODING, NULL);
    if (rc < 0) {
        dcp_log(LOG_ERROR,"xmlTextWriterStartDocument failed");
        return DCP_FATAL;
    }

    xmlTextWriterStartElement(xml, BAD_CAST "CompositionPlaylist");
    xmlTextWriterWriteAttribute(xml, BAD_CAST "xmlns", BAD_CAST NS_CPL[opendcp->ns]);
    if (opendcp->xml_signature.sign) {
        xmlTextWriterWriteAttribute(xml, BAD_CAST "xmlns:dsig", BAD_CAST DS_DSIG);
    }

    /* cpl attributes */
    xmlTextWriterWriteFormatElement(xml, BAD_CAST "Id","%s%s","urn:uuid:",cpl->uuid);
    xmlTextWriterWriteFormatElement(xml, BAD_CAST "AnnotationText","%s",cpl->annotation);
    xmlTextWriterWriteFormatElement(xml, BAD_CAST "IssueDate","%s",cpl->timestamp);
    xmlTextWriterWriteFormatElement(xml, BAD_CAST "Creator","%s",cpl->creator);
    xmlTextWriterWriteFormatElement(xml, BAD_CAST "ContentTitleText","%s",cpl->title);
    xmlTextWriterWriteFormatElement(xml, BAD_CAST "ContentKind","%s",cpl->kind);

    /* content version */
    if (opendcp->ns == XML_NS_SMPTE) {
        xmlTextWriterStartElement(xml, BAD_CAST "ContentVersion"); 
        xmlTextWriterWriteFormatElement(xml, BAD_CAST "Id","%s%s_%s","urn:uri:",cpl->uuid,cpl->timestamp);
        xmlTextWriterWriteFormatElement(xml, BAD_CAST "LabelText","%s_%s",cpl->uuid,cpl->timestamp);
        xmlTextWriterEndElement(xml);
    }

    /* rating */
    xmlTextWriterStartElement(xml, BAD_CAST "RatingList");
    if (strcmp(cpl->rating,"")) {
        xmlTextWriterWriteFormatElement(xml, BAD_CAST "Agency","%s",RATING_AGENCY[1]);
        xmlTextWriterWriteFormatElement(xml, BAD_CAST "Label","%s",cpl->rating);
    }
    xmlTextWriterEndElement(xml);

    /* reel(s) Start */
    xmlTextWriterStartElement(xml, BAD_CAST "ReelList");
    for (r=0;r<cpl->reel_count;r++) {
        reel_t reel = cpl->reel[r];
        xmlTextWriterStartElement(xml, BAD_CAST "Reel");
        xmlTextWriterWriteFormatElement(xml, BAD_CAST "Id","%s%s","urn:uuid:",reel.uuid);
        xmlTextWriterStartElement(xml, BAD_CAST "AssetList");

        /* Asset(s) Start */
        for (a=0;a<cpl->reel[r].asset_count;a++) {
            asset_t asset = cpl->reel[r].asset[a];
            if (asset.essence_class == ACT_PICTURE) {
                if (asset.stereoscopic) {
                    xmlTextWriterStartElement(xml, BAD_CAST "msp-cpl:MainStereoscopicPicture");
                    xmlTextWriterWriteAttribute(xml, BAD_CAST "xmlns:msp-cpl", BAD_CAST NS_CPL_3D[opendcp->ns]);
                } else {
                    xmlTextWriterStartElement(xml, BAD_CAST "MainPicture");
                }
            }
            if (asset.essence_class == ACT_SOUND) {
                xmlTextWriterStartElement(xml, BAD_CAST "MainSound");
            }
            if (asset.essence_class == ACT_TIMED_TEXT) {
                xmlTextWriterStartElement(xml, BAD_CAST "MainSubtitle");
            }

            xmlTextWriterWriteFormatElement(xml, BAD_CAST "Id","%s%s","urn:uuid:",asset.uuid);
            xmlTextWriterWriteFormatElement(xml, BAD_CAST "AnnotationText","%s",asset.annotation);
            xmlTextWriterWriteFormatElement(xml, BAD_CAST "EditRate","%s",asset.edit_rate);
            xmlTextWriterWriteFormatElement(xml, BAD_CAST "IntrinsicDuration","%d",asset.intrinsic_duration);
            xmlTextWriterWriteFormatElement(xml, BAD_CAST "EntryPoint","%d",asset.entry_point);
            xmlTextWriterWriteFormatElement(xml, BAD_CAST "Duration","%d",asset.duration);

            if (asset.essence_class == ACT_PICTURE) {
                xmlTextWriterWriteFormatElement(xml, BAD_CAST "FrameRate","%s",asset.frame_rate);
                if (opendcp->ns == XML_NS_SMPTE) {
                    xmlTextWriterWriteFormatElement(xml, BAD_CAST "ScreenAspectRatio","%s",asset.aspect_ratio);
                } else {
                    xmlTextWriterWriteFormatElement(xml, BAD_CAST "ScreenAspectRatio","%s",get_aspect_ratio(asset.aspect_ratio));
                }
            }

            if ( opendcp->xml.digest_flag ) {
                xmlTextWriterWriteFormatElement(xml, BAD_CAST "Hash","%s",asset.digest);
            }
            
            xmlTextWriterEndElement(xml); /* end asset */
        }
     
        xmlTextWriterEndElement(xml);     /* end assetlist */
        xmlTextWriterEndElement(xml);     /* end reel */
    }
    xmlTextWriterEndElement(xml);         /* end reel list */

#ifdef XMLSEC
    if (opendcp->xml_signature.sign) {
        write_dsig_template(opendcp, xml);
    }
#endif

    xmlTextWriterEndElement(xml);         /* end compositionplaylist */

    rc = xmlTextWriterEndDocument(xml);
    if (rc < 0) {
        dcp_log(LOG_ERROR,"xmlTextWriterEndDocument failed %s",cpl->filename);
        return DCP_FATAL;
    }

    xmlFreeTextWriter(xml);
    xmlSaveFormatFile(cpl->filename, doc, 1);
    xmlFreeDoc(doc);

#ifdef XMLSEC
    /* sign the XML file */
    if (opendcp->xml_signature.sign) {
        xml_sign(opendcp, cpl->filename);
    }
#endif

    /* store CPL file size */
    dcp_log(LOG_INFO,"Writing CPL file info");
    stat(cpl->filename, &st);
    sprintf(cpl->size,"%"PRIu64,st.st_size);
    calculate_digest(cpl->filename,cpl->digest);
    
    return DCP_SUCCESS;
}
コード例 #17
0
ファイル: opendcp_j2k.c プロジェクト: kzbb/OpenDCP
int convert_to_j2k(opendcp_t *opendcp, char *in_file, char *out_file, char *tmp_path) {
    odcp_image_t *odcp_image;
    int result = 0;

    if (tmp_path == NULL) {
        tmp_path = "./";
    }
    dcp_log(LOG_DEBUG,"%-15.15s: reading input file %s","convert_to_j2k",in_file);
     
    #ifdef OPENMP
    #pragma omp critical
    #endif
    {
    result = read_image(&odcp_image,in_file); 
    }

    if (result != OPENDCP_NO_ERROR) {
        dcp_log(LOG_ERROR,"Unable to read file %s",in_file);
        return OPENDCP_ERROR;
    }

    if (!odcp_image) {
        dcp_log(LOG_ERROR,"Unable to load file %s",in_file);
        return OPENDCP_ERROR;
    }

    /* verify image is dci compliant */
    if (check_image_compliance(opendcp->cinema_profile, odcp_image, NULL) != OPENDCP_NO_ERROR) {
        dcp_log(LOG_WARN,"The image resolution of %s is not DCI Compliant",in_file);

        /* resize image */
        if (opendcp->j2k.resize) {
            if (resize(&odcp_image, opendcp->cinema_profile, opendcp->j2k.resize) != OPENDCP_NO_ERROR) {
                odcp_image_free(odcp_image);
                return OPENDCP_ERROR;
            }
        } else {
            odcp_image_free(odcp_image);
            return OPENDCP_ERROR;
        }
    }
    
    if (opendcp->j2k.xyz) {
        dcp_log(LOG_INFO,"RGB->XYZ color conversion %s",in_file);
        if (rgb_to_xyz(odcp_image,opendcp->j2k.lut,opendcp->j2k.xyz_method)) {
            dcp_log(LOG_ERROR,"Color conversion failed %s",in_file);
            odcp_image_free(odcp_image);
            return OPENDCP_ERROR;
        }
    }

    if ( opendcp->j2k.encoder == J2K_KAKADU ) {
        char tempfile[255];
        sprintf(tempfile,"%s/tmp_%s",tmp_path,basename(in_file));
        dcp_log(LOG_DEBUG,"%-15.15s: Writing temporary tif %s","convert_to_j2k",tempfile);
        result = write_tif(odcp_image,tempfile,0);
        odcp_image_free(odcp_image);
        
        if (result != OPENDCP_NO_ERROR) {
            dcp_log(LOG_ERROR,"Writing temporary tif failed");
            return OPENDCP_ERROR;
        }

        result = encode_kakadu(opendcp, tempfile, out_file);
        if ( result != OPENDCP_NO_ERROR) {
            dcp_log(LOG_ERROR,"Kakadu JPEG2000 conversion failed %s",in_file);
            remove(tempfile);
            return OPENDCP_ERROR;
        }
        remove(tempfile);
    } else {
        opj_image_t *opj_image;
        odcp_to_opj(odcp_image, &opj_image); 
        odcp_image_free(odcp_image);
        if (encode_openjpeg(opendcp,opj_image,out_file) != OPENDCP_NO_ERROR) {
            dcp_log(LOG_ERROR,"OpenJPEG JPEG2000 conversion failed %s",in_file);
            opj_image_destroy(opj_image);
            return OPENDCP_ERROR;
        }        
        opj_image_destroy(opj_image);
    }

    return OPENDCP_NO_ERROR;
}
コード例 #18
0
ファイル: opendcp_xml.c プロジェクト: eugen-kugler/OpenDCP
int write_assetmap(opendcp_t *opendcp) {
    xmlIndentTreeOutput = 1;
    xmlDocPtr        doc;
    xmlTextWriterPtr xml;
    int              a,c,r,rc;
    char             uuid_s[40];
    cpl_t            cpl;
    reel_t           reel;

    /* generate assetmap UUID */
    uuid_random(uuid_s);

    dcp_log(LOG_INFO,"Writing ASSETMAP file %.256s",opendcp->assetmap.filename);

    /* create XML document */
    xml = xmlNewTextWriterDoc(&doc,0);

    /* assetmap XML Start */
    rc = xmlTextWriterStartDocument(xml, NULL, XML_ENCODING, NULL);
    if (rc < 0) {
        dcp_log(LOG_ERROR,"xmlTextWriterStartDocument failed");
        return DCP_FATAL;
    }

    xmlTextWriterStartElement(xml, BAD_CAST "AssetMap");
    xmlTextWriterWriteAttribute(xml, BAD_CAST "xmlns", BAD_CAST NS_AM[opendcp->ns]);

    /* assetmap attributes */
    xmlTextWriterWriteFormatElement(xml, BAD_CAST "Id","%s%s","urn:uuid:",uuid_s);
    xmlTextWriterWriteFormatElement(xml, BAD_CAST "Creator","%s",opendcp->xml.creator);
    xmlTextWriterWriteFormatElement(xml, BAD_CAST "VolumeCount","%d",1);
    xmlTextWriterWriteFormatElement(xml, BAD_CAST "IssueDate","%s",opendcp->xml.timestamp);
    xmlTextWriterWriteFormatElement(xml, BAD_CAST "Issuer","%s",opendcp->xml.issuer);

    xmlTextWriterStartElement(xml, BAD_CAST "AssetList");

    dcp_log(LOG_INFO,"Writing ASSETMAP PKL");

    /* PKL */
    xmlTextWriterStartElement(xml, BAD_CAST "Asset");
    xmlTextWriterWriteFormatElement(xml, BAD_CAST "Id","%s%s","urn:uuid:",opendcp->pkl[0].uuid);
    xmlTextWriterWriteFormatElement(xml, BAD_CAST "PackingList","%s","true");
    xmlTextWriterStartElement(xml, BAD_CAST "ChunkList");
    xmlTextWriterStartElement(xml, BAD_CAST "Chunk");
    xmlTextWriterWriteFormatElement(xml, BAD_CAST "Path","%s",basename(opendcp->pkl[0].filename));
    xmlTextWriterWriteFormatElement(xml, BAD_CAST "VolumeIndex","%d",1);
    xmlTextWriterWriteFormatElement(xml, BAD_CAST "Offset","%d",0);
    xmlTextWriterWriteFormatElement(xml, BAD_CAST "Length","%s",opendcp->pkl[0].size);
    xmlTextWriterEndElement(xml); /* end chunk */
    xmlTextWriterEndElement(xml); /* end chunklist */
    xmlTextWriterEndElement(xml); /* end pkl asset */
  
    dcp_log(LOG_INFO,"Writing ASSETMAP CPLs");

    /* CPL */
    for (c=0;c<opendcp->pkl[0].cpl_count;c++) {
        cpl = opendcp->pkl[0].cpl[c];
        xmlTextWriterStartElement(xml, BAD_CAST "Asset");
        xmlTextWriterWriteFormatElement(xml, BAD_CAST "Id","%s%s","urn:uuid:",cpl.uuid);
        xmlTextWriterStartElement(xml, BAD_CAST "ChunkList");
        xmlTextWriterStartElement(xml, BAD_CAST "Chunk");
        xmlTextWriterWriteFormatElement(xml, BAD_CAST "Path","%s",basename(cpl.filename));
        xmlTextWriterWriteFormatElement(xml, BAD_CAST "VolumeIndex","%d",1);
        xmlTextWriterWriteFormatElement(xml, BAD_CAST "Offset","%d",0);
        xmlTextWriterWriteFormatElement(xml, BAD_CAST "Length","%s",cpl.size);
        xmlTextWriterEndElement(xml); /* end chunk */
        xmlTextWriterEndElement(xml); /* end chunklist */
        xmlTextWriterEndElement(xml); /* end cpl asset */

        /* assets(s) start */
        for (r=0;r<cpl.reel_count;r++) {
            reel = cpl.reel[r];
            for (a=0;a<reel.asset_count;a++) {
                asset_t asset = reel.asset[a];
                xmlTextWriterStartElement(xml, BAD_CAST "Asset");
                xmlTextWriterWriteFormatElement(xml, BAD_CAST "Id","%s%s","urn:uuid:",asset.uuid);
                xmlTextWriterStartElement(xml, BAD_CAST "ChunkList");
                xmlTextWriterStartElement(xml, BAD_CAST "Chunk");
                xmlTextWriterWriteFormatElement(xml, BAD_CAST "Path","%s",basename(asset.filename));
                xmlTextWriterWriteFormatElement(xml, BAD_CAST "VolumeIndex","%d",1);
                xmlTextWriterWriteFormatElement(xml, BAD_CAST "Offset","%d",0);
                xmlTextWriterWriteFormatElement(xml, BAD_CAST "Length","%s",asset.size);
                xmlTextWriterEndElement(xml); /* end chunk */
                xmlTextWriterEndElement(xml); /* end chunklist */
                xmlTextWriterEndElement(xml); /* end cpl asset */
            }
        }
    }

    xmlTextWriterEndElement(xml); /* end assetlist */
    xmlTextWriterEndElement(xml); /* end assetmap */

    rc = xmlTextWriterEndDocument(xml);
    if (rc < 0) {
        dcp_log(LOG_ERROR,"xmlTextWriterEndDocument failed %s",opendcp->assetmap.filename);
        return DCP_FATAL;
    }

    xmlFreeTextWriter(xml);
    xmlSaveFormatFile(opendcp->assetmap.filename, doc, 1);
    xmlFreeDoc(doc);

    return DCP_SUCCESS;
}
コード例 #19
0
ファイル: opendcp_xml.c プロジェクト: eugen-kugler/OpenDCP
int write_pkl(opendcp_t *opendcp, pkl_t *pkl) {
    int a,r,c,rc;
    struct stat st;
    xmlIndentTreeOutput = 1;
    xmlDocPtr        doc;
    xmlTextWriterPtr xml;

    /* create XML document */
    xml = xmlNewTextWriterDoc(&doc,0);

    /* pkl start */
    rc = xmlTextWriterStartDocument(xml, NULL, XML_ENCODING, NULL);
    if (rc < 0) {
        dcp_log(LOG_ERROR,"xmlTextWriterStartDocument failed");
        return DCP_FATAL;
    }

    xmlTextWriterStartElement(xml, BAD_CAST "PackingList");
    xmlTextWriterWriteAttribute(xml, BAD_CAST "xmlns", BAD_CAST NS_PKL[opendcp->ns]);
    if (opendcp->xml_signature.sign) {
        xmlTextWriterWriteAttribute(xml, BAD_CAST "xmlns:dsig", BAD_CAST DS_DSIG);
    }

    /* cpl attributes */
    xmlTextWriterWriteFormatElement(xml, BAD_CAST "Id","%s%s","urn:uuid:",pkl->uuid);
    xmlTextWriterWriteFormatElement(xml, BAD_CAST "AnnotationText","%s",pkl->annotation);
    xmlTextWriterWriteFormatElement(xml, BAD_CAST "IssueDate","%s",opendcp->xml.timestamp);
    xmlTextWriterWriteFormatElement(xml, BAD_CAST "Issuer","%s",opendcp->xml.issuer);
    xmlTextWriterWriteFormatElement(xml, BAD_CAST "Creator","%s",opendcp->xml.creator);

    dcp_log(LOG_INFO,"CPLS: %d",pkl->cpl_count);

    /* asset(s) Start */
    xmlTextWriterStartElement(xml, BAD_CAST "AssetList");
    for (c=0;c<pkl->cpl_count;c++) {
        cpl_t cpl = pkl->cpl[c];
        dcp_log(LOG_INFO,"REELS: %d",cpl.reel_count);
        for (r=0;r<cpl.reel_count;r++) {
            reel_t reel = cpl.reel[r];

            for (a=0;a<reel.asset_count;a++) {
                asset_t asset = reel.asset[a];
                xmlTextWriterStartElement(xml, BAD_CAST "Asset");
                xmlTextWriterWriteFormatElement(xml, BAD_CAST "Id","%s%s","urn:uuid:",asset.uuid);
                xmlTextWriterWriteFormatElement(xml, BAD_CAST "AnnotationText","%s",asset.annotation);
                xmlTextWriterWriteFormatElement(xml, BAD_CAST "Hash","%s",asset.digest);
                xmlTextWriterWriteFormatElement(xml, BAD_CAST "Size","%s",asset.size);
                if (opendcp->ns == XML_NS_SMPTE) {
                    xmlTextWriterWriteFormatElement(xml, BAD_CAST "Type","%s","application/mxf");
                } else {
                    if (asset.essence_class == ACT_PICTURE) {
                        xmlTextWriterWriteFormatElement(xml, BAD_CAST "Type","%s","application/x-smpte-mxf;asdcpKind=Picture");
                    }
                    if (asset.essence_class == ACT_SOUND) {
                        xmlTextWriterWriteFormatElement(xml, BAD_CAST "Type","%s","application/x-smpte-mxf;asdcpKind=Sound");
                    }
                    if (asset.essence_class == ACT_TIMED_TEXT) {
                        xmlTextWriterWriteFormatElement(xml, BAD_CAST "Type","%s","application/x-smpte-mxf;asdcpKind=Subtitle");
                    }
                }
                xmlTextWriterEndElement(xml);      /* end asset */
            }
        }

        /* cpl */
        xmlTextWriterStartElement(xml, BAD_CAST "Asset");
        xmlTextWriterWriteFormatElement(xml, BAD_CAST "Id","%s%s","urn:uuid:",cpl.uuid);
        xmlTextWriterWriteFormatElement(xml, BAD_CAST "Hash","%s",cpl.digest);
        xmlTextWriterWriteFormatElement(xml, BAD_CAST "Size","%s",cpl.size);
        if (opendcp->ns == XML_NS_SMPTE) {
            xmlTextWriterWriteFormatElement(xml, BAD_CAST "Type","%s","text/xml");
        } else {
            xmlTextWriterWriteFormatElement(xml, BAD_CAST "Type","%s","text/xml;asdcpKind=CPL");
        }
        xmlTextWriterEndElement(xml);      /* end cpl asset */
    }
    xmlTextWriterEndElement(xml);      /* end assetlist */

#ifdef XMLSEC
    if (opendcp->xml_signature.sign) {
        write_dsig_template(opendcp, xml);
    }
#endif

    xmlTextWriterEndElement(xml);      /* end packinglist */

    rc = xmlTextWriterEndDocument(xml);
    if (rc < 0) {
        dcp_log(LOG_ERROR,"xmlTextWriterEndDocument failed %s",pkl->filename);
        return DCP_FATAL;
    }

    xmlFreeTextWriter(xml);
    xmlSaveFormatFile(pkl->filename, doc, 1);
    xmlFreeDoc(doc);

#ifdef XMLSEC
    /* sign the XML file */
    if (opendcp->xml_signature.sign) {
        xml_sign(opendcp, pkl->filename);
    }
#endif

    /* store PKL file size */
    stat(pkl->filename, &st);
    sprintf(pkl->size,"%"PRIu64,st.st_size);

    return DCP_SUCCESS;
}
コード例 #20
0
ファイル: opendcp_j2k.c プロジェクト: kzbb/OpenDCP
int encode_openjpeg(opendcp_t *opendcp, opj_image_t *opj_image, char *out_file) {
    bool result;
    int codestream_length;
    int max_comp_size;
    int max_cs_len;
    opj_cparameters_t parameters;
    opj_cio_t *cio = NULL;
    opj_cinfo_t *cinfo = NULL;
    FILE *f = NULL; 
    int bw;
   
    if (opendcp->j2k.bw) {
        bw = opendcp->j2k.bw;
    } else {
        bw = MAX_DCP_JPEG_BITRATE;
    }

    /* set the max image and component sizes based on frame_rate */
    max_cs_len = ((float)bw)/8/opendcp->frame_rate;
 
    /* adjust cs for 3D */
    if (opendcp->stereoscopic) {
        max_cs_len = max_cs_len/2;
    } 
 
    max_comp_size = ((float)max_cs_len)/1.25;

    /* set encoding parameters to default values */
    opj_set_default_encoder_parameters(&parameters);

    /* set default cinema parameters */
    set_cinema_encoder_parameters(opendcp, &parameters);

    parameters.cp_comment = (char*)malloc(strlen(OPENDCP_NAME)+1);
    sprintf(parameters.cp_comment,"%s", OPENDCP_NAME);

    /* adjust cinema enum type */
    if (opendcp->cinema_profile == DCP_CINEMA4K) {
        parameters.cp_cinema = CINEMA4K_24;
    } else {
        parameters.cp_cinema = CINEMA2K_24;
    }

    /* Decide if MCT should be used */
    parameters.tcp_mct = opj_image->numcomps == 3 ? 1 : 0;

    /* set max image */
    parameters.max_comp_size = max_comp_size;
    parameters.tcp_rates[0]= ((float) (opj_image->numcomps * opj_image->comps[0].w * opj_image->comps[0].h * opj_image->comps[0].prec))/
                              (max_cs_len * 8 * opj_image->comps[0].dx * opj_image->comps[0].dy);

    /* get a J2K compressor handle */
    dcp_log(LOG_DEBUG,"%-15.15s: creating compressor %s","encode_openjpeg",out_file);
    cinfo = opj_create_compress(CODEC_J2K);

    /* set event manager to null (openjpeg 1.3 bug) */
    cinfo->event_mgr = NULL;

    /* setup the encoder parameters using the current image and user parameters */
    dcp_log(LOG_DEBUG,"%-15.15s: setup J2k encoder %s","encode_openjpeg",out_file);
    opj_setup_encoder(cinfo, &parameters, opj_image);

    /* open a byte stream for writing */
    /* allocate memory for all tiles */
    dcp_log(LOG_DEBUG,"%-15.15s: opening J2k output stream %s","encode_openjpeg",out_file);
    cio = opj_cio_open((opj_common_ptr)cinfo, NULL, 0);

    dcp_log(LOG_INFO,"Encoding file %s",out_file);
    result = opj_encode(cinfo, cio, opj_image, NULL);
    dcp_log(LOG_DEBUG,"%-15.15s: encoding file %s complete","encode_openjepg",out_file);

    if (!result) {
        dcp_log(LOG_ERROR,"Unable to encode jpeg2000 file %s",out_file);
        opj_cio_close(cio);
        opj_destroy_compress(cinfo);
        return OPENDCP_ERROR;
    }
      
    codestream_length = cio_tell(cio);

    f = fopen(out_file, "wb");

    if (!f) {
        dcp_log(LOG_ERROR,"Unable to write jpeg2000 file %s",out_file);
        opj_cio_close(cio);
        opj_destroy_compress(cinfo);
        return OPENDCP_ERROR;
    }

    fwrite(cio->buffer, 1, codestream_length, f);
    fclose(f);

    /* free openjpeg structure */
    opj_cio_close(cio);
    opj_destroy_compress(cinfo);

    /* free user parameters structure */
    if(parameters.cp_comment) free(parameters.cp_comment);
    if(parameters.cp_matrice) free(parameters.cp_matrice);

    return OPENDCP_NO_ERROR;
}