Esempio n. 1
0
/// Given data types a and b, return a type that is a best guess for one
/// that can handle both without any loss of range or precision.
TypeDesc::BASETYPE
ImageBufAlgo::type_merge (TypeDesc::BASETYPE a, TypeDesc::BASETYPE b)
{
    // Same type already? done.
    if (a == b)
        return a;
    if (a == TypeDesc::UNKNOWN)
        return b;
    if (b == TypeDesc::UNKNOWN)
        return a;
    // Canonicalize so a's size (in bytes) is >= b's size in bytes. This
    // unclutters remaining cases.
    if (TypeDesc(a).size() < TypeDesc(b).size())
        std::swap (a, b);
    // Double or float trump anything else
    if (a == TypeDesc::DOUBLE || a == TypeDesc::FLOAT)
        return a;
    if (a == TypeDesc::UINT32 && (b == TypeDesc::UINT16 || b == TypeDesc::UINT8))
        return a;
    if (a == TypeDesc::INT32 && (b == TypeDesc::INT16 || b == TypeDesc::UINT16 ||
                                 b == TypeDesc::INT8 || b == TypeDesc::UINT8))
        return a;
    if ((a == TypeDesc::UINT16 || a == TypeDesc::HALF) && b == TypeDesc::UINT8)
        return a;
    if ((a == TypeDesc::INT16 || a == TypeDesc::HALF) &&
        (b == TypeDesc::INT8 || b == TypeDesc::UINT8))
        return a;
    // Out of common cases. For all remaining edge cases, punt and say that
    // we prefer float.
    return TypeDesc::FLOAT;
}
Esempio n. 2
0
TypeSpec
OSLCompilerImpl::type_from_code (const char *code, int *advance)
{
    TypeSpec t;
    int i = 0;
    switch (code[i]) {
    case 'i' : t = TypeDesc::TypeInt;          break;
    case 'f' : t = TypeDesc::TypeFloat;        break;
    case 'c' : t = TypeDesc::TypeColor;        break;
    case 'p' : t = TypeDesc::TypePoint;        break;
    case 'v' : t = TypeDesc::TypeVector;       break;
    case 'n' : t = TypeDesc::TypeNormal;       break;
    case 'm' : t = TypeDesc::TypeMatrix;       break;
    case 's' : t = TypeDesc::TypeString;       break;
    case 'x' : t = TypeDesc (TypeDesc::NONE);  break;
    case 'X' : t = TypeDesc (TypeDesc::PTR);   break;
    case 'L' : t = TypeDesc (TypeDesc::LONGLONG); break;
    case 'C' : // color closure
        t = TypeSpec (TypeDesc::TypeColor, true);
        break;
    case 'S' : // structure
        // Following the 'S' is the numeric structure ID
        t = TypeSpec ("struct", atoi (code+i+1));
        // Skip to the last digit
        while (isdigit(code[i+1]))
            ++i;
        break;
    case '?' : break; // anything will match, so keep 'UNKNOWN'
    case '*' : break; // anything will match, so keep 'UNKNOWN'
    case '.' : break; // anything will match, so keep 'UNKNOWN'
    default:
        std::cerr << "Don't know how to decode type code '" 
                  << code << "' " << (int)code[0] << "\n";
        ASSERT (0);   // FIXME
        if (advance)
            *advance = 1;
        return TypeSpec();
    }
    ++i;

    if (code[i] == '[') {
        ++i;
        t.make_array (-1);   // signal arrayness, unknown length
        if (isdigit(code[i]) || code[i] == ']') {
            if (isdigit(code[i]))
                t.make_array (atoi (code+i));
            while (isdigit(code[i]))
                ++i;
            if (code[i] == ']')
                ++i;
        }
    }

    if (advance)
        *advance = i;
    return t;
}
Esempio n. 3
0
void benchmark_convert_type ()
{
    const size_t size = 10000000;
    const S testval(1.0);
    std::vector<S> svec (size, testval);
    std::vector<D> dvec (size);
    std::cout << Strutil::format("Benchmark conversion of %6s -> %6s : ",
                                 TypeDesc(BaseTypeFromC<S>::value),
                                 TypeDesc(BaseTypeFromC<D>::value));
    float time = time_trial (bind (do_convert_type<S,D>, OIIO::cref(svec), OIIO::ref(dvec)),
                             ntrials, iterations) / iterations;
    std::cout << Strutil::format ("%7.1f Mvals/sec", (size/1.0e6)/time) << std::endl;
    D r = convert_type<S,D>(testval);
    OIIO_CHECK_EQUAL (dvec[size-1], r);
}
Esempio n. 4
0
bool
JpgInput::read_icc_profile(j_decompress_ptr cinfo, ImageSpec& spec)
{
    int num_markers = 0;
    std::vector<unsigned char> icc_buf;
    unsigned int total_length = 0;
    const int MAX_SEQ_NO      = 255;
    unsigned char marker_present
        [MAX_SEQ_NO
         + 1];  // one extra is used to store the flag if marker is found, set to one if marker is found
    unsigned int data_length[MAX_SEQ_NO + 1];  // store the size of each marker
    unsigned int data_offset[MAX_SEQ_NO + 1];  // store the offset of each marker
    memset(marker_present, 0, (MAX_SEQ_NO + 1));

    for (jpeg_saved_marker_ptr m = cinfo->marker_list; m; m = m->next) {
        if (m->marker == (JPEG_APP0 + 2)
            && !strcmp((const char*)m->data, "ICC_PROFILE")) {
            if (num_markers == 0)
                num_markers = GETJOCTET(m->data[13]);
            else if (num_markers != GETJOCTET(m->data[13]))
                return false;
            int seq_no = GETJOCTET(m->data[12]);
            if (seq_no <= 0 || seq_no > num_markers)
                return false;
            if (marker_present[seq_no])  // duplicate marker
                return false;
            marker_present[seq_no] = 1;  // flag found marker
            data_length[seq_no]    = m->data_length - ICC_HEADER_SIZE;
        }
    }
    if (num_markers == 0)
        return false;

    // checking for missing markers
    for (int seq_no = 1; seq_no <= num_markers; seq_no++) {
        if (marker_present[seq_no] == 0)
            return false;  // missing sequence number
        data_offset[seq_no] = total_length;
        total_length += data_length[seq_no];
    }

    if (total_length == 0)
        return false;  // found only empty markers

    icc_buf.resize(total_length * sizeof(JOCTET));

    // and fill it in
    for (jpeg_saved_marker_ptr m = cinfo->marker_list; m; m = m->next) {
        if (m->marker == (JPEG_APP0 + 2)
            && !strcmp((const char*)m->data, "ICC_PROFILE")) {
            int seq_no = GETJOCTET(m->data[12]);
            memcpy(&icc_buf[0] + data_offset[seq_no], m->data + ICC_HEADER_SIZE,
                   data_length[seq_no]);
        }
    }
    spec.attribute(ICC_PROFILE_ATTR, TypeDesc(TypeDesc::UINT8, total_length),
                   &icc_buf[0]);
    return true;
}
Esempio n. 5
0
static void
test_gettextureinfo (ustring filename)
{
    bool ok;

    int res[2] = {0};
    ok = texsys->get_texture_info (filename, 0, ustring("resolution"),
                                   TypeDesc(TypeDesc::INT,2), res);
    std::cerr << "Result of get_texture_info resolution = " << ok << ' ' << res[0] << 'x' << res[1] << "\n";

    int chan = 0;
    ok = texsys->get_texture_info (filename, 0, ustring("channels"),
                                   TypeDesc::INT, &chan);
    std::cerr << "Result of get_texture_info channels = " << ok << ' ' << chan << "\n";

    float fchan = 0;
    ok = texsys->get_texture_info (filename, 0, ustring("channels"),
                                   TypeDesc::FLOAT, &fchan);
    std::cerr << "Result of get_texture_info channels = " << ok << ' ' << fchan << "\n";

    int dataformat = 0;
    ok = texsys->get_texture_info (filename, 0, ustring("format"),
                                   TypeDesc::INT, &dataformat);
    std::cerr << "Result of get_texture_info data format = " << ok << ' ' 
              << TypeDesc((TypeDesc::BASETYPE)dataformat).c_str() << "\n";

    const char *datetime = NULL;
    ok = texsys->get_texture_info (filename, 0, ustring("DateTime"),
                                   TypeDesc::STRING, &datetime);
    std::cerr << "Result of get_texture_info datetime = " << ok << ' ' 
              << (datetime ? datetime : "") << "\n";

    const char *texturetype = NULL;
    ok = texsys->get_texture_info (filename, 0, ustring("textureformat"),
                                   TypeDesc::STRING, &texturetype);
    std::cerr << "Texture type is " << ok << ' '
              << (texturetype ? texturetype : "") << "\n";
    std::cerr << "\n";
}
Esempio n. 6
0
void
ImageBuf::set_full (int xbegin, int xend, int ybegin, int yend,
                    int zbegin, int zend, const float *bordercolor)
{
    m_spec.full_x = xbegin;
    m_spec.full_y = ybegin;
    m_spec.full_z = zbegin;
    m_spec.full_width  = xend - xbegin;
    m_spec.full_height = yend - ybegin;
    m_spec.full_depth  = zend - zbegin;
    if (bordercolor)
        m_spec.attribute ("oiio:bordercolor",
                          TypeDesc(TypeDesc::FLOAT,m_spec.nchannels),
                          bordercolor);
}
Esempio n. 7
0
TypeSpec
ASTconditional_statement::typecheck (TypeSpec expected)
{
    typecheck_list (cond ());
    oslcompiler->push_nesting (false);
    typecheck_list (truestmt ());
    typecheck_list (falsestmt ());
    oslcompiler->pop_nesting (false);

    TypeSpec c = cond()->typespec();
    if (c.is_closure())
        error ("Cannot use a closure as an 'if' condition");
    if (c.is_structure())
        error ("Cannot use a struct as an 'if' condition");
    if (c.is_array())
        error ("Cannot use an array as an 'if' condition");
    return m_typespec = TypeDesc (TypeDesc::NONE);
}
Esempio n. 8
0
TypeSpec
ASTloop_statement::typecheck (TypeSpec expected)
{
    typecheck_list (init ());
    oslcompiler->push_nesting (true);
    typecheck_list (cond ());
    typecheck_list (iter ());
    typecheck_list (stmt ());
    oslcompiler->pop_nesting (true);

    TypeSpec c = cond()->typespec();
    if (c.is_closure())
        error ("Cannot use a closure as an '%s' condition", opname());
    if (c.is_structure())
        error ("Cannot use a struct as an '%s' condition", opname());
    if (c.is_array())
        error ("Cannot use an array as an '%s' condition", opname());
    return m_typespec = TypeDesc (TypeDesc::NONE);
}
Esempio n. 9
0
void
OpenEXRInput::PartInfo::query_channels (const Imf::Header *header)
{
    ASSERT (! initialized);
    spec.nchannels = 0;
    const Imf::ChannelList &channels (header->channels());
    std::vector<std::string> channelnames;  // Order of channels in file
    std::vector<ChanNameHolder> cnh;
    int c = 0;
    for (Imf::ChannelList::ConstIterator ci = channels.begin();
         ci != channels.end();  ++c, ++ci) {
        cnh.emplace_back (ci.name(), c, ci.channel().type);
        ++spec.nchannels;
    }
    std::sort (cnh.begin(), cnh.end(), ChanNameHolder::compare_cnh);
    // Now we should have cnh sorted into the order that we want to present
    // to the OIIO client.
    spec.format = TypeDesc::UNKNOWN;
    bool all_one_format = true;
    for (int c = 0; c < spec.nchannels; ++c) {
        spec.channelnames.push_back (cnh[c].fullname);
        spec.channelformats.push_back (cnh[c].datatype);
        spec.format = TypeDesc(ImageBufAlgo::type_merge (TypeDesc::BASETYPE(spec.format.basetype),
                                                         TypeDesc::BASETYPE(cnh[c].datatype.basetype)));
        pixeltype.push_back (cnh[c].exr_data_type);
        chanbytes.push_back (cnh[c].datatype.size());
        all_one_format &= (cnh[c].datatype == cnh[0].datatype);
        if (spec.alpha_channel < 0 && (Strutil::iequals (cnh[c].suffix, "A") ||
                                       Strutil::iequals (cnh[c].suffix, "Alpha")))
            spec.alpha_channel = c;
        if (spec.z_channel < 0 && (Strutil::iequals (cnh[c].suffix, "Z") ||
                                   Strutil::iequals (cnh[c].suffix, "Depth")))
            spec.z_channel = c;
    }
    ASSERT ((int)spec.channelnames.size() == spec.nchannels);
    ASSERT (spec.format != TypeDesc::UNKNOWN);
    if (all_one_format)
        spec.channelformats.clear();
}
Esempio n. 10
0
static void
print_component (std::ostream &out, const ClosureComponent *comp, ShadingSystemImpl *ss, const Color3 &weight)
{
    out << "(" << weight[0]*comp->w[0] << ", " << weight[1]*comp->w[1] << ", " << weight[2]*comp->w[2] << ") * ";
    const ClosureRegistry::ClosureEntry *clentry = ss->find_closure(comp->id);
    ASSERT(clentry);
    out << clentry->name.c_str() << " (";
    int i;
    for (i = 0; i < clentry->nformal; ++i) {
        if (i) out << ", ";
        if (clentry->params[i].type.numelements() > 1) out << "[";
        for (size_t j = 0; j < clentry->params[i].type.numelements(); ++j) {
            if (j) out << ", ";
            print_component_value(out, ss, clentry->params[i].type.elementtype(),
                                  (const char *)comp->data() + clentry->params[i].offset
                                                             + clentry->params[i].type.elementsize() * j);
        }
        if (clentry->params[i].type.numelements() > 1) out << "]";
    }
    if (comp->nattrs) {
        const ClosureComponent::Attr * attrs = comp->attrs();
        for (int j = 0; j < comp->nattrs; ++j) {
            if (i || j) out << ", ";
            // find the type
            TypeDesc td;
            for (int p = 0; p < clentry->nkeyword; ++p)
                if (!strcmp(clentry->params[clentry->nformal + p].key, attrs[j].key.c_str()))
                    td = clentry->params[clentry->nformal + p].type;
            if (td != TypeDesc()) {
                out << "\"" << attrs[j].key.c_str() << "\", ";
                print_component_value(out, ss, td, &attrs[j].value);
            }
        }
    }
    out << ")";
}
Esempio n. 11
0
bool
NullInput::open(const std::string& name, ImageSpec& newspec,
                const ImageSpec& config)
{
    m_filename = name;
    m_subimage = -1;
    m_miplevel = -1;
    m_mip      = false;
    m_topspec  = config;

    // std::vector<std::pair<string_view,string_view> > args;
    // string_view filename = deconstruct_uri (name, &args);
    std::map<std::string, std::string> args;
    std::string filename;
    if (!Strutil::get_rest_arguments(name, filename, args))
        return false;
    if (filename.empty())
        return false;

    // To keep the "null" input reader from reading from ANY name, only
    // succeed if it ends in ".null" or ".nul" --OR-- if the config has a
    // special override "null:force" set to nonzero (that lets the caller
    // guarantee a null input even if the name has no extension, say).
    if (!Strutil::ends_with(filename, ".null")
        && !Strutil::ends_with(filename, ".nul")
        && config.get_int_attribute("null:force") == 0)
        return false;

    // Override the config with default resolution if it was not set
    if (m_topspec.width <= 0)
        m_topspec.width = 1024;
    if (m_topspec.height <= 0)
        m_topspec.height = 1024;
    if (m_topspec.depth <= 0)
        m_topspec.depth = 1;
    if (m_topspec.full_width <= 0)
        m_topspec.full_width = m_topspec.width;
    if (m_topspec.full_height <= 0)
        m_topspec.full_height = m_topspec.height;
    if (m_topspec.full_depth <= 0)
        m_topspec.full_depth = m_topspec.depth;
    if (m_topspec.nchannels <= 0)
        m_topspec.nchannels = 4;
    if (m_topspec.format == TypeUnknown)
        m_topspec.format = TypeFloat;

    m_filename = filename;
    std::vector<float> fvalue;

    for (const auto& a : args) {
        if (a.first == "RES") {
            parse_res(a.second, m_topspec.width, m_topspec.height,
                      m_topspec.depth);
            m_topspec.full_x      = m_topspec.x;
            m_topspec.full_y      = m_topspec.y;
            m_topspec.full_z      = m_topspec.z;
            m_topspec.full_width  = m_topspec.width;
            m_topspec.full_height = m_topspec.height;
            m_topspec.full_depth  = m_topspec.depth;
        } else if (a.first == "TILE" || a.first == "TILES") {
            parse_res(a.second, m_topspec.tile_width, m_topspec.tile_height,
                      m_topspec.tile_depth);
        } else if (a.first == "CHANNELS") {
            m_topspec.nchannels = Strutil::from_string<int>(a.second);
            m_topspec.default_channel_names();
        } else if (a.first == "MIP") {
            m_mip = Strutil::from_string<int>(a.second);
        } else if (a.first == "TEX") {
            if (Strutil::from_string<int>(a.second)) {
                if (!m_spec.tile_width) {
                    m_topspec.tile_width  = 64;
                    m_topspec.tile_height = 64;
                    m_topspec.tile_depth  = 1;
                }
                m_topspec.attribute("wrapmodes", "black,black");
                m_topspec.attribute("textureformat", "Plain Texture");
                m_mip = true;
            }
        } else if (a.first == "TYPE") {
            m_topspec.set_format(TypeDesc(a.second));
        } else if (a.first == "PIXEL") {
            Strutil::extract_from_list_string(fvalue, a.second);
            fvalue.resize(m_topspec.nchannels);
        } else if (a.first.size() && a.second.size()) {
            parse_param(a.first, a.second, m_topspec);
        }
    }

    if (fvalue.size()) {
        // Convert float to the native type
        fvalue.resize(m_topspec.nchannels, 0.0f);
        m_value.resize(m_topspec.pixel_bytes());
        convert_types(TypeFloat, fvalue.data(), m_topspec.format,
                      m_value.data(), m_topspec.nchannels);
    }

    bool ok = seek_subimage(0, 0);
    newspec = spec();
    return ok;
}
Esempio n. 12
0
bool
DPXInput::seek_subimage (int subimage, int miplevel, ImageSpec &newspec)
{
    if (miplevel != 0)
        return false;
    if (subimage < 0 || subimage >= m_dpx.header.ImageElementCount ())
        return false;

    m_subimage = subimage;

    // check if the client asked us for raw data
    m_wantRaw = newspec.get_int_attribute ("dpx:RawData", 0) != 0;

    // create imagespec
    TypeDesc typedesc;
    switch (m_dpx.header.ComponentDataSize(subimage)) {
        case dpx::kByte:
            typedesc = m_dpx.header.DataSign (subimage)
                ? TypeDesc::INT8 : TypeDesc::UINT8;
            break;
        case dpx::kWord:
            typedesc = m_dpx.header.DataSign (subimage)
                ? TypeDesc::INT16 : TypeDesc::UINT16;
            break;
        case dpx::kInt:
            typedesc = m_dpx.header.DataSign (subimage)
                ? TypeDesc::INT32 : TypeDesc::UINT32;
            break;
        case dpx::kFloat:
            typedesc = TypeDesc::FLOAT;
            break;
        case dpx::kDouble:
            typedesc = TypeDesc::DOUBLE;
            break;
        default:
            error ("Invalid component data size");
            return false;
    }
    m_spec = ImageSpec (m_dpx.header.Width(), m_dpx.header.Height(),
        m_dpx.header.ImageElementComponentCount(subimage), typedesc);
    // fill channel names
    m_spec.channelnames.clear ();
    switch (m_dpx.header.ImageDescriptor(subimage)) {
        /*case dpx::kUserDefinedDescriptor:
            break;*/
        case dpx::kRed:
            m_spec.channelnames.push_back("R");
            break;
        case dpx::kGreen:
            m_spec.channelnames.push_back("G");
            break;
        case dpx::kBlue:
            m_spec.channelnames.push_back("B");
            break;
        case dpx::kAlpha:
            m_spec.channelnames.push_back("A");
            m_spec.alpha_channel = 0;
            break;
        case dpx::kLuma:
            // FIXME: do we treat this as intensity or do we use Y' as per
            // convention to differentiate it from linear luminance?
            m_spec.channelnames.push_back("Y'");
            break;
        case dpx::kDepth:
            m_spec.channelnames.push_back("Z");
            m_spec.z_channel = 0;
            break;
        /*case dpx::kCompositeVideo:
            break;*/
        case dpx::kRGB:
        case dpx::kRGBA:
        case dpx::kABGR:    // colour converter will swap the bytes for us
            m_spec.default_channel_names ();
            break;
        case dpx::kCbYCrY:
            if (m_wantRaw) {
                m_spec.channelnames.push_back("CbCr");
                m_spec.channelnames.push_back("Y");
            } else {
                m_spec.nchannels = 3;
                m_spec.default_channel_names ();
            }
            break;
        case dpx::kCbYACrYA:
            if (m_wantRaw) {
                m_spec.channelnames.push_back("CbCr");
                m_spec.channelnames.push_back("Y");
                m_spec.channelnames.push_back("A");
                m_spec.alpha_channel = 2;
            } else {
                m_spec.nchannels = 4;
                m_spec.default_channel_names ();
            }
            break;
        case dpx::kCbYCr:
            if (m_wantRaw) {
                m_spec.channelnames.push_back("Cb");
                m_spec.channelnames.push_back("Y");
                m_spec.channelnames.push_back("Cr");
            } else
                m_spec.default_channel_names ();
            break;
        case dpx::kCbYCrA:
            if (m_wantRaw) {
                m_spec.channelnames.push_back("Cb");
                m_spec.channelnames.push_back("Y");
                m_spec.channelnames.push_back("Cr");
                m_spec.channelnames.push_back("A");
                m_spec.alpha_channel = 3;
            } else {
                m_spec.default_channel_names ();
            }
            break;
        default:
            {
                for (int i = 0;
                    i < m_dpx.header.ImageElementComponentCount(subimage); i++) {
                    std::string ch = "channel" + i;
                    m_spec.channelnames.push_back(ch);
                }
            }
    }
    // bits per pixel
    m_spec.attribute ("oiio:BitsPerSample", m_dpx.header.BitDepth(subimage));
    // image orientation - see appendix B.2 of the OIIO documentation
    int orientation;
    switch (m_dpx.header.ImageOrientation ()) {
        case dpx::kLeftToRightTopToBottom:
            orientation = 1;
            break;
        case dpx::kRightToLeftTopToBottom:
            orientation = 2;
            break;
        case dpx::kLeftToRightBottomToTop:
            orientation = 4;
            break;
        case dpx::kRightToLeftBottomToTop:
            orientation = 3;
            break;
        case dpx::kTopToBottomLeftToRight:
            orientation = 5;
            break;
        case dpx::kTopToBottomRightToLeft:
            orientation = 6;
            break;
        case dpx::kBottomToTopLeftToRight:
            orientation = 8;
            break;
        case dpx::kBottomToTopRightToLeft:
            orientation = 7;
            break;
        default:
            orientation = 0;
            break;
    }
    m_spec.attribute ("Orientation", orientation);

    // image linearity
    switch (m_dpx.header.Transfer (subimage)) {
        case dpx::kLinear:
            m_spec.attribute ("oiio:ColorSpace", "Linear");
            break;
        case dpx::kLogarithmic:
            m_spec.attribute ("oiio:ColorSpace", "KodakLog");
            break;
        case dpx::kITUR709:
            m_spec.attribute ("oiio:ColorSpace", "Rec709");
            break;
        case dpx::kUserDefined:
            if (! isnan (m_dpx.header.Gamma ()) && m_dpx.header.Gamma () != 0) {
                m_spec.attribute ("oiio:ColorSpace", "GammaCorrected");
                m_spec.attribute ("oiio:Gamma", (float) m_dpx.header.Gamma ());
                break;
            }
            // intentional fall-through
        /*case dpx::kPrintingDensity:
        case dpx::kUnspecifiedVideo:
        case dpx::kSMPTE274M:
        case dpx::kITUR601:
        case dpx::kITUR602:
        case dpx::kNTSCCompositeVideo:
        case dpx::kPALCompositeVideo:
        case dpx::kZLinear:
        case dpx::kZHomogeneous:
        case dpx::kUndefinedCharacteristic:*/
        default:
            break;
    }
    m_spec.attribute ("dpx:Transfer",
        get_characteristic_string (m_dpx.header.Transfer (subimage)));
    // colorimetric characteristic
    m_spec.attribute ("dpx:Colorimetric",
        get_characteristic_string (m_dpx.header.Colorimetric (subimage)));

    // general metadata
    // some non-compliant writers will dump a field filled with 0xFF rather
    // than a NULL string termination on the first character, so take that
    // into account, too
    if (m_dpx.header.copyright[0] && m_dpx.header.copyright[0] != (char)0xFF)
        m_spec.attribute ("Copyright", m_dpx.header.copyright);
    if (m_dpx.header.creator[0] && m_dpx.header.creator[0] != (char)0xFF)
        m_spec.attribute ("Software", m_dpx.header.creator);
    if (m_dpx.header.project[0] && m_dpx.header.project[0] != (char)0xFF)
        m_spec.attribute ("DocumentName", m_dpx.header.project);
    if (m_dpx.header.creationTimeDate[0]) {
        // libdpx's date/time format is pretty close to OIIO's (libdpx uses
        // %Y:%m:%d:%H:%M:%S%Z)
        char date[24];
        strcpy(date, m_dpx.header.creationTimeDate);
        date[10] = ' ';
        date[19] = 0;
        m_spec.attribute ("DateTime", date);
    }
    if (m_dpx.header.ImageEncoding (subimage) == dpx::kRLE)
        m_spec.attribute ("compression", "rle");
    char buf[32 + 1];
    m_dpx.header.Description (subimage, buf);
    if (buf[0] && buf[0] != -1)
        m_spec.attribute ("ImageDescription", buf);
    m_spec.attribute ("PixelAspectRatio", m_dpx.header.AspectRatio(0)
         / (float)m_dpx.header.AspectRatio(1));

    // DPX-specific metadata
    m_spec.attribute ("dpx:ImageDescriptor",
        get_descriptor_string (m_dpx.header.ImageDescriptor (subimage)));
    // save some typing by using macros
    // "internal" macros
#define DPX_SET_ATTRIB_S(x, n, s)   m_spec.attribute (s,                      \
                                        m_dpx.header.x (n))
#define DPX_SET_ATTRIB(x, n)        DPX_SET_ATTRIB_S(x, n, "dpx:" #x)
    // set without checking for bogus attributes
#define DPX_SET_ATTRIB_N(x)         DPX_SET_ATTRIB(x, subimage)
    // set with checking for bogus attributes
#define DPX_SET_ATTRIB_BYTE(x)      if (m_dpx.header.x () != 0xFF)      \
                                        DPX_SET_ATTRIB(x, )
#define DPX_SET_ATTRIB_INT_N(x)     if (m_dpx.header.x (subimage) != 0xFFFFFFFF) \
                                        DPX_SET_ATTRIB(x, subimage)
#define DPX_SET_ATTRIB_INT(x)       if (m_dpx.header.x () != 0xFFFFFFFF)      \
                                        DPX_SET_ATTRIB(x, )
#define DPX_SET_ATTRIB_FLOAT_N(x)   if (! isnan(m_dpx.header.x (subimage)))      \
                                        DPX_SET_ATTRIB(x, subimage)
#define DPX_SET_ATTRIB_FLOAT(x)     if (! isnan(m_dpx.header.x ()))           \
                                        DPX_SET_ATTRIB(x, )
    // see comment above Copyright, Software and DocumentName
#define DPX_SET_ATTRIB_STR(X, x)    if (m_dpx.header.x[0]                     \
                                        && m_dpx.header.x[0] != -1)           \
                                        m_spec.attribute ("dpx:" #X,          \
                                            m_dpx.header.x)

    DPX_SET_ATTRIB_INT(EncryptKey);
    DPX_SET_ATTRIB_INT(DittoKey);
    DPX_SET_ATTRIB_INT_N(LowData);
    DPX_SET_ATTRIB_FLOAT_N(LowQuantity);
    DPX_SET_ATTRIB_INT_N(HighData);
    DPX_SET_ATTRIB_FLOAT_N(HighQuantity);
    DPX_SET_ATTRIB_FLOAT(XScannedSize);
    DPX_SET_ATTRIB_FLOAT(YScannedSize);
    DPX_SET_ATTRIB_INT(FramePosition);
    DPX_SET_ATTRIB_INT(SequenceLength);
    DPX_SET_ATTRIB_INT(HeldCount);
    DPX_SET_ATTRIB_FLOAT(FrameRate);
    DPX_SET_ATTRIB_FLOAT(ShutterAngle);
    DPX_SET_ATTRIB_STR(Version, version);
    DPX_SET_ATTRIB_STR(Format, format);
    DPX_SET_ATTRIB_STR(FrameId, frameId);
    DPX_SET_ATTRIB_STR(SlateInfo, slateInfo);
    DPX_SET_ATTRIB_STR(SourceImageFileName, sourceImageFileName);
    DPX_SET_ATTRIB_STR(InputDevice, inputDevice);
    DPX_SET_ATTRIB_STR(InputDeviceSerialNumber, inputDeviceSerialNumber);
    DPX_SET_ATTRIB_BYTE(Interlace);
    DPX_SET_ATTRIB_BYTE(FieldNumber);
    DPX_SET_ATTRIB_FLOAT(HorizontalSampleRate);
    DPX_SET_ATTRIB_FLOAT(VerticalSampleRate);
    DPX_SET_ATTRIB_FLOAT(TemporalFrameRate);
    DPX_SET_ATTRIB_FLOAT(TimeOffset);
    DPX_SET_ATTRIB_FLOAT(BlackLevel);
    DPX_SET_ATTRIB_FLOAT(BlackGain);
    DPX_SET_ATTRIB_FLOAT(BreakPoint);
    DPX_SET_ATTRIB_FLOAT(WhiteLevel);
    DPX_SET_ATTRIB_FLOAT(IntegrationTimes);

#undef DPX_SET_ATTRIB_STR
#undef DPX_SET_ATTRIB_FLOAT
#undef DPX_SET_ATTRIB_FLOAT_N
#undef DPX_SET_ATTRIB_INT
#undef DPX_SET_ATTRIB_INT_N
#undef DPX_SET_ATTRIB_N
#undef DPX_SET_ATTRIB
#undef DPX_SET_ATTRIB_S

    std::string tmpstr;
    switch (m_dpx.header.ImagePacking (subimage)) {
        case dpx::kPacked:
            tmpstr = "Packed";
            break;
        case dpx::kFilledMethodA:
            tmpstr = "Filled, method A";
            break;
        case dpx::kFilledMethodB:
            tmpstr = "Filled, method B";
            break;
    }
    if (!tmpstr.empty ())
        m_spec.attribute ("dpx:Packing", tmpstr);

    if (m_dpx.header.timeCode != 0xFFFFFFFF)
        m_spec.attribute ("dpx:TimeCode", m_dpx.header.timeCode);
    if (m_dpx.header.userBits != 0xFFFFFFFF)
        m_spec.attribute ("dpx:UserBits", m_dpx.header.userBits);
    if (m_dpx.header.sourceTimeDate[0]) {
        // libdpx's date/time format is pretty close to OIIO's (libdpx uses
        // %Y:%m:%d:%H:%M:%S%Z)
        char date[24];
        strcpy(date, m_dpx.header.sourceTimeDate);
        date[10] = ' ';
        date[19] = 0;
        m_spec.attribute ("dpx:SourceDateTime", date);
    }
    m_dpx.header.FilmEdgeCode(buf);
    if (buf[0])
        m_spec.attribute ("dpx:FilmEdgeCode", buf);

    tmpstr.clear ();
    switch (m_dpx.header.Signal ()) {
        case dpx::kUndefined:
            tmpstr = "Undefined";
            break;
        case dpx::kNTSC:
            tmpstr = "NTSC";
            break;
        case dpx::kPAL:
            tmpstr = "PAL";
            break;
        case dpx::kPAL_M:
            tmpstr = "PAL-M";
            break;
        case dpx::kSECAM:
            tmpstr = "SECAM";
            break;
        case dpx::k525LineInterlace43AR:
            tmpstr = "YCbCr ITU-R 601-5 525i, 4:3";
            break;
        case dpx::k625LineInterlace43AR:
            tmpstr = "YCbCr ITU-R 601-5 625i, 4:3";
            break;
        case dpx::k525LineInterlace169AR:
            tmpstr = "YCbCr ITU-R 601-5 525i, 16:9";
            break;
        case dpx::k625LineInterlace169AR:
            tmpstr = "YCbCr ITU-R 601-5 625i, 16:9";
            break;
        case dpx::k1050LineInterlace169AR:
            tmpstr = "YCbCr 1050i, 16:9";
            break;
        case dpx::k1125LineInterlace169AR_274:
            tmpstr = "YCbCr 1125i, 16:9 (SMPTE 274M)";
            break;
        case dpx::k1250LineInterlace169AR:
            tmpstr = "YCbCr 1250i, 16:9";
            break;
        case dpx::k1125LineInterlace169AR_240:
            tmpstr = "YCbCr 1125i, 16:9 (SMPTE 240M)";
            break;
        case dpx::k525LineProgressive169AR:
            tmpstr = "YCbCr 525p, 16:9";
            break;
        case dpx::k625LineProgressive169AR:
            tmpstr = "YCbCr 625p, 16:9";
            break;
        case dpx::k750LineProgressive169AR:
            tmpstr = "YCbCr 750p, 16:9 (SMPTE 296M)";
            break;
        case dpx::k1125LineProgressive169AR:
            tmpstr = "YCbCr 1125p, 16:9 (SMPTE 274M)";
            break;
        case 0xFF:
            // don't set the attribute at all
            break;
        default:
            tmpstr = Strutil::format ("Undefined %d",
                (int)m_dpx.header.Signal ());
            break;
    }
    if (!tmpstr.empty ())
        m_spec.attribute ("dpx:Signal", tmpstr);

    // read in user data; don't bother if the buffer is already filled (user
    // data is per-file, not per-element)
    if (m_userBuf.empty () && m_dpx.header.UserSize () != 0
        && m_dpx.header.UserSize () != 0xFFFFFFFF) {
        m_userBuf.resize (m_dpx.header.UserSize ());
        m_dpx.ReadUserData (&m_userBuf[0]);
    }
    if (!m_userBuf.empty ())
        m_spec.attribute ("dpx:UserData", TypeDesc (TypeDesc::UCHAR,
            m_dpx.header.UserSize ()), &m_userBuf[0]);

    dpx::Block block(0, 0, m_dpx.header.Width () - 1, 0);
    int bufsize = dpx::QueryRGBBufferSize (m_dpx.header, subimage, block);
    if (bufsize == 0 && !m_wantRaw) {
        error ("Unable to deliver RGB data from source data");
        return false;
    } else if (!m_wantRaw && bufsize > 0)
        m_dataPtr = new unsigned char[bufsize];
    else
        // no need to allocate another buffer
        m_dataPtr = NULL;
    
    newspec = m_spec;
    return true;
}
Esempio n. 13
0
void
OpenEXRInput::PartInfo::parse_header (const Imf::Header *header)
{
    if (initialized)
        return;

    ASSERT (header);
    spec = ImageSpec();

    top_datawindow = header->dataWindow();
    top_displaywindow = header->displayWindow();
    spec.x = top_datawindow.min.x;
    spec.y = top_datawindow.min.y;
    spec.z = 0;
    spec.width  = top_datawindow.max.x - top_datawindow.min.x + 1;
    spec.height = top_datawindow.max.y - top_datawindow.min.y + 1;
    spec.depth = 1;
    topwidth = spec.width;      // Save top-level mipmap dimensions
    topheight = spec.height;
    spec.full_x = top_displaywindow.min.x;
    spec.full_y = top_displaywindow.min.y;
    spec.full_z = 0;
    spec.full_width  = top_displaywindow.max.x - top_displaywindow.min.x + 1;
    spec.full_height = top_displaywindow.max.y - top_displaywindow.min.y + 1;
    spec.full_depth = 1;
    spec.tile_depth = 1;

    if (header->hasTileDescription()
          && Strutil::icontains(header->type(), "tile")) {
        const Imf::TileDescription &td (header->tileDescription());
        spec.tile_width = td.xSize;
        spec.tile_height = td.ySize;
        levelmode = td.mode;
        roundingmode = td.roundingMode;
        if (levelmode == Imf::MIPMAP_LEVELS)
            nmiplevels = numlevels (std::max(topwidth,topheight), roundingmode);
        else if (levelmode == Imf::RIPMAP_LEVELS)
            nmiplevels = numlevels (std::max(topwidth,topheight), roundingmode);
        else
            nmiplevels = 1;
    } else {
        spec.tile_width = 0;
        spec.tile_height = 0;
        levelmode = Imf::ONE_LEVEL;
        nmiplevels = 1;
    }
    query_channels (header);   // also sets format

    spec.deep = Strutil::istarts_with (header->type(), "deep");

    // Unless otherwise specified, exr files are assumed to be linear.
    spec.attribute ("oiio:ColorSpace", "Linear");

    if (levelmode != Imf::ONE_LEVEL)
        spec.attribute ("openexr:roundingmode", roundingmode);

    const Imf::EnvmapAttribute *envmap;
    envmap = header->findTypedAttribute<Imf::EnvmapAttribute>("envmap");
    if (envmap) {
        cubeface = (envmap->value() == Imf::ENVMAP_CUBE);
        spec.attribute ("textureformat", cubeface ? "CubeFace Environment" : "LatLong Environment");
        // OpenEXR conventions for env maps
        if (! cubeface)
            spec.attribute ("oiio:updirection", "y");
        spec.attribute ("oiio:sampleborder", 1);
        // FIXME - detect CubeFace Shadow?
    } else {
        cubeface = false;
        if (spec.tile_width && levelmode == Imf::MIPMAP_LEVELS)
            spec.attribute ("textureformat", "Plain Texture");
        // FIXME - detect Shadow
    }

    const Imf::CompressionAttribute *compressattr;
    compressattr = header->findTypedAttribute<Imf::CompressionAttribute>("compression");
    if (compressattr) {
        const char *comp = NULL;
        switch (compressattr->value()) {
        case Imf::NO_COMPRESSION    : comp = "none"; break;
        case Imf::RLE_COMPRESSION   : comp = "rle"; break;
        case Imf::ZIPS_COMPRESSION  : comp = "zips"; break;
        case Imf::ZIP_COMPRESSION   : comp = "zip"; break;
        case Imf::PIZ_COMPRESSION   : comp = "piz"; break;
        case Imf::PXR24_COMPRESSION : comp = "pxr24"; break;
#ifdef IMF_B44_COMPRESSION
            // The enum Imf::B44_COMPRESSION is not defined in older versions
            // of OpenEXR, and there are no explicit version numbers in the
            // headers.  BUT this other related #define is present only in
            // the newer version.
        case Imf::B44_COMPRESSION   : comp = "b44"; break;
        case Imf::B44A_COMPRESSION  : comp = "b44a"; break;
#endif
#if defined(OPENEXR_VERSION_MAJOR) && \
    (OPENEXR_VERSION_MAJOR*10000+OPENEXR_VERSION_MINOR*100+OPENEXR_VERSION_PATCH) >= 20200
        case Imf::DWAA_COMPRESSION  : comp = "dwaa"; break;
        case Imf::DWAB_COMPRESSION  : comp = "dwab"; break;
#endif
        default:
            break;
        }
        if (comp)
            spec.attribute ("compression", comp);
    }

    for (Imf::Header::ConstIterator hit = header->begin();
             hit != header->end();  ++hit) {
        const Imf::IntAttribute *iattr;
        const Imf::FloatAttribute *fattr;
        const Imf::StringAttribute *sattr;
        const Imf::M33fAttribute *m33fattr;
        const Imf::M44fAttribute *m44fattr;
        const Imf::V3fAttribute *v3fattr;
        const Imf::V3iAttribute *v3iattr;
        const Imf::V2fAttribute *v2fattr;
        const Imf::V2iAttribute *v2iattr;
        const Imf::Box2iAttribute *b2iattr;
        const Imf::Box2fAttribute *b2fattr;
        const Imf::TimeCodeAttribute *tattr;
        const Imf::KeyCodeAttribute *kcattr;
        const Imf::ChromaticitiesAttribute *crattr;
        const Imf::RationalAttribute *rattr;
        const Imf::StringVectorAttribute *svattr;
        const Imf::DoubleAttribute *dattr;
        const Imf::V2dAttribute *v2dattr;
        const Imf::V3dAttribute *v3dattr;
        const Imf::M33dAttribute *m33dattr;
        const Imf::M44dAttribute *m44dattr;
        const char *name = hit.name();
        std::string oname = exr_tag_to_oiio_std[name];
        if (oname.empty())   // Empty string means skip this attrib
            continue;
//        if (oname == name)
//            oname = std::string(format_name()) + "_" + oname;
        const Imf::Attribute &attrib = hit.attribute();
        std::string type = attrib.typeName();
        if (type == "string" &&
            (sattr = header->findTypedAttribute<Imf::StringAttribute> (name)))
            spec.attribute (oname, sattr->value().c_str());
        else if (type == "int" &&
            (iattr = header->findTypedAttribute<Imf::IntAttribute> (name)))
            spec.attribute (oname, iattr->value());
        else if (type == "float" &&
            (fattr = header->findTypedAttribute<Imf::FloatAttribute> (name)))
            spec.attribute (oname, fattr->value());
        else if (type == "m33f" &&
            (m33fattr = header->findTypedAttribute<Imf::M33fAttribute> (name)))
            spec.attribute (oname, TypeMatrix33, &(m33fattr->value()));
        else if (type == "m44f" &&
            (m44fattr = header->findTypedAttribute<Imf::M44fAttribute> (name)))
            spec.attribute (oname, TypeMatrix44, &(m44fattr->value()));
        else if (type == "v3f" &&
                 (v3fattr = header->findTypedAttribute<Imf::V3fAttribute> (name)))
            spec.attribute (oname, TypeVector, &(v3fattr->value()));
        else if (type == "v3i" &&
                 (v3iattr = header->findTypedAttribute<Imf::V3iAttribute> (name))) {
            TypeDesc v3 (TypeDesc::INT, TypeDesc::VEC3, TypeDesc::VECTOR);
            spec.attribute (oname, v3, &(v3iattr->value()));
        }
        else if (type == "v2f" &&
                 (v2fattr = header->findTypedAttribute<Imf::V2fAttribute> (name))) {
            TypeDesc v2 (TypeDesc::FLOAT,TypeDesc::VEC2);
            spec.attribute (oname, v2, &(v2fattr->value()));
        }
        else if (type == "v2i" &&
                 (v2iattr = header->findTypedAttribute<Imf::V2iAttribute> (name))) {
            TypeDesc v2 (TypeDesc::INT,TypeDesc::VEC2);
            spec.attribute (oname, v2, &(v2iattr->value()));
        }
        else if (type == "stringvector" &&
            (svattr = header->findTypedAttribute<Imf::StringVectorAttribute> (name))) {
            std::vector<std::string> strvec = svattr->value();
            std::vector<ustring> ustrvec (strvec.size());
            for (size_t i = 0, e = strvec.size();  i < e;  ++i)
                ustrvec[i] = strvec[i];
            TypeDesc sv (TypeDesc::STRING, ustrvec.size());
            spec.attribute(oname, sv, &ustrvec[0]);
        }
        else if (type == "double" &&
            (dattr = header->findTypedAttribute<Imf::DoubleAttribute> (name))) {
            TypeDesc d (TypeDesc::DOUBLE);
            spec.attribute (oname, d, &(dattr->value()));
        }
        else if (type == "v2d" &&
                 (v2dattr = header->findTypedAttribute<Imf::V2dAttribute> (name))) {
            TypeDesc v2 (TypeDesc::DOUBLE,TypeDesc::VEC2);
            spec.attribute (oname, v2, &(v2dattr->value()));
        }
        else if (type == "v3d" &&
                 (v3dattr = header->findTypedAttribute<Imf::V3dAttribute> (name))) {
            TypeDesc v3 (TypeDesc::DOUBLE,TypeDesc::VEC3, TypeDesc::VECTOR);
            spec.attribute (oname, v3, &(v3dattr->value()));
        }
        else if (type == "m33d" &&
            (m33dattr = header->findTypedAttribute<Imf::M33dAttribute> (name))) {
            TypeDesc m33 (TypeDesc::DOUBLE, TypeDesc::MATRIX33);
            spec.attribute (oname, m33, &(m33dattr->value()));
        }
        else if (type == "m44d" &&
            (m44dattr = header->findTypedAttribute<Imf::M44dAttribute> (name))) {
            TypeDesc m44 (TypeDesc::DOUBLE, TypeDesc::MATRIX44);
            spec.attribute (oname, m44, &(m44dattr->value()));
        }
        else if (type == "box2i" &&
                 (b2iattr = header->findTypedAttribute<Imf::Box2iAttribute> (name))) {
            TypeDesc bx (TypeDesc::INT, TypeDesc::VEC2, 2);
            spec.attribute (oname, bx, &b2iattr->value());
        }
        else if (type == "box2f" &&
                 (b2fattr = header->findTypedAttribute<Imf::Box2fAttribute> (name))) {
            TypeDesc bx (TypeDesc::FLOAT, TypeDesc::VEC2, 2);
            spec.attribute (oname, bx, &b2fattr->value());
        }
        else if (type == "timecode" &&
                 (tattr = header->findTypedAttribute<Imf::TimeCodeAttribute> (name))) {
            unsigned int timecode[2];
            timecode[0] = tattr->value().timeAndFlags(Imf::TimeCode::TV60_PACKING); //TV60 returns unchanged _time
            timecode[1] = tattr->value().userData();

            // Elevate "timeCode" to smpte:TimeCode
            if (oname == "timeCode")
                oname = "smpte:TimeCode";
            spec.attribute(oname, TypeTimeCode, timecode);
        }
        else if (type == "keycode" &&
                 (kcattr = header->findTypedAttribute<Imf::KeyCodeAttribute> (name))) {
            const Imf::KeyCode *k = &kcattr->value();
            unsigned int keycode[7];
            keycode[0] = k->filmMfcCode();
            keycode[1] = k->filmType();
            keycode[2] = k->prefix();
            keycode[3] = k->count();
            keycode[4] = k->perfOffset();
            keycode[5] = k->perfsPerFrame();
            keycode[6] = k->perfsPerCount();

            // Elevate "keyCode" to smpte:KeyCode
            if (oname == "keyCode")
                oname = "smpte:KeyCode";
            spec.attribute(oname, TypeKeyCode, keycode);
        } else if (type == "chromaticities" &&
                   (crattr = header->findTypedAttribute<Imf::ChromaticitiesAttribute> (name))) {
            const Imf::Chromaticities *chroma = &crattr->value();
            spec.attribute (oname, TypeDesc(TypeDesc::FLOAT,8),
                            (const float *)chroma);
        } 
        else if (type == "rational" &&
                   (rattr = header->findTypedAttribute<Imf::RationalAttribute> (name))) {
            const Imf::Rational *rational = &rattr->value();
            int n = rational->n;
            unsigned int d = rational->d;
            if (d < (1UL << 31)) {
                int r[2];
                r[0] = n;
                r[1] = static_cast<int>(d);
                spec.attribute (oname, TypeRational, r);    
            } else if (int f = static_cast<int>(boost::math::gcd<long int>(rational[0], rational[1])) > 1) {
                int r[2];
                r[0] = n / f;
                r[1] = static_cast<int>(d / f);
               spec.attribute (oname, TypeRational, r);
            } else {
                // TODO: find a way to allow the client to accept "close" rational values
                OIIO::debug ("Don't know what to do with OpenEXR Rational attribute %s with value %d / %u that we cannot represent exactly", oname, n, d);
            }
        }
        else {
#if 0
            std::cerr << "  unknown attribute " << type << ' ' << name << "\n";
#endif
        }
    }

    float aspect = spec.get_float_attribute ("PixelAspectRatio", 0.0f);
    float xdensity = spec.get_float_attribute ("XResolution", 0.0f);
    if (xdensity) {
        // If XResolution is found, supply the YResolution and unit.
        spec.attribute ("YResolution", xdensity * (aspect ? aspect : 1.0f));
        spec.attribute ("ResolutionUnit", "in"); // EXR is always pixels/inch
    }

    // EXR "name" also gets passed along as "oiio:subimagename".
    if (header->hasName())
        spec.attribute ("oiio:subimagename", header->name());

    // Squash some problematic texture metadata if we suspect it's wrong
    pvt::check_texture_metadata_sanity (spec);

    initialized = true;
}
Esempio n. 14
0
IplImage *
ImageBufAlgo::to_IplImage (const ImageBuf &src)
{
#ifdef USE_OPENCV
    ImageBuf tmp = src;
    ImageSpec spec = tmp.spec();

    // Make sure the image buffer is initialized.
    if (!tmp.initialized() && !tmp.read(tmp.subimage(), tmp.miplevel(), true)) {
        DASSERT (0 && "Could not initialize ImageBuf.");
        return NULL;
    }

    int dstFormat;
    TypeDesc dstSpecFormat;
    if (spec.format == TypeDesc(TypeDesc::UINT8)) {
        dstFormat = IPL_DEPTH_8U;
        dstSpecFormat = spec.format;
    } else if (spec.format == TypeDesc(TypeDesc::INT8)) {
        dstFormat = IPL_DEPTH_8S;
        dstSpecFormat = spec.format;
    } else if (spec.format == TypeDesc(TypeDesc::UINT16)) {
        dstFormat = IPL_DEPTH_16U;
        dstSpecFormat = spec.format;
    } else if (spec.format == TypeDesc(TypeDesc::INT16)) {
        dstFormat = IPL_DEPTH_16S;
        dstSpecFormat = spec.format;
    } else if (spec.format == TypeDesc(TypeDesc::HALF)) {
        dstFormat = IPL_DEPTH_32F;
        // OpenCV does not support half types. Switch to float instead.
        dstSpecFormat = TypeDesc(TypeDesc::FLOAT);
    } else if (spec.format == TypeDesc(TypeDesc::FLOAT)) {
        dstFormat = IPL_DEPTH_32F;
        dstSpecFormat = spec.format;
    } else if (spec.format == TypeDesc(TypeDesc::DOUBLE)) {
        dstFormat = IPL_DEPTH_64F;
        dstSpecFormat = spec.format;
    } else {
        DASSERT (0 && "Unknown data format in ImageBuf.");
        return NULL;
    }
    IplImage *ipl = cvCreateImage(cvSize(spec.width, spec.height), dstFormat, spec.nchannels);
    if (!ipl) {
        DASSERT (0 && "Unable to create IplImage.");
        return NULL;
    }

    size_t pixelsize = dstSpecFormat.size() * spec.nchannels;
    // Account for the origin in the line step size, to end up with the
    // standard OIIO origin-at-upper-left:
    size_t linestep = ipl->origin ? -ipl->widthStep : ipl->widthStep;

    bool converted = convert_image(spec.nchannels, spec.width, spec.height, 1,
                                   tmp.localpixels(), spec.format,
                                   spec.pixel_bytes(), spec.scanline_bytes(), 0,
                                   ipl->imageData, dstSpecFormat,
                                   pixelsize, linestep, 0);

    if (!converted) {
        DASSERT (0 && "convert_image failed.");
        cvReleaseImage(&ipl);
        return NULL;
    }

    // OpenCV uses BGR ordering
    if (spec.nchannels == 3) {
        cvCvtColor(ipl, ipl, CV_RGB2BGR);
    } else if (spec.nchannels == 4) {
        cvCvtColor(ipl, ipl, CV_RGBA2BGRA);
    }

    return ipl;
#else
    return NULL;
#endif
}
Esempio n. 15
0
bool
ImageBuf::read (int subimage, int miplevel, bool force, TypeDesc convert,
               ProgressCallback progress_callback,
               void *progress_callback_data)
{
    if (pixels_valid() && !force &&
            subimage == this->subimage() && miplevel == this->miplevel())
        return true;

    if (! init_spec (m_name.string(), subimage, miplevel)) {
        m_badfile = true;
        m_spec_valid = false;
        return false;
    }

    // Set our current spec to the requested subimage
    if (! m_imagecache->get_imagespec (m_name, m_spec, subimage, miplevel) ||
        ! m_imagecache->get_imagespec (m_name, m_nativespec, subimage, miplevel, true)) {
        m_err = m_imagecache->geterror ();
        return false;
    }
    m_current_subimage = subimage;
    m_current_miplevel = miplevel;

#if 1
    // If we don't already have "local" pixels, and we aren't asking to
    // convert the pixels to a specific (and different) type, then take an
    // early out by relying on the cache.
    int peltype = TypeDesc::UNKNOWN;
    m_imagecache->get_image_info (m_name, subimage, miplevel,
                                  ustring("cachedpixeltype"),
                                  TypeDesc::TypeInt, &peltype);
    m_cachedpixeltype = TypeDesc ((TypeDesc::BASETYPE)peltype);
    if (! m_localpixels && ! force &&
        (convert == m_cachedpixeltype || convert == TypeDesc::UNKNOWN)) {
        m_spec.format = m_cachedpixeltype;
#ifdef DEBUG
        std::cerr << "read was not necessary -- using cache\n";
#endif
        return true;
    } else {
#ifdef DEBUG
        std::cerr << "going to have to read " << m_name << ": "
                  << m_spec.format.c_str() << " vs " << convert.c_str() << "\n";
#endif
    }        
#endif

    if (convert != TypeDesc::UNKNOWN)
        m_spec.format = convert;
    m_orientation = m_spec.get_int_attribute ("orientation", 1);
    m_pixelaspect = m_spec.get_float_attribute ("pixelaspectratio", 1.0f);

    realloc ();
    if (m_imagecache->get_pixels (m_name, subimage, miplevel,
                                  m_spec.x, m_spec.x+m_spec.width,
                                  m_spec.y, m_spec.y+m_spec.height,
                                  m_spec.z, m_spec.z+m_spec.depth,
                                  m_spec.format, &m_pixels[0])) {
        m_pixels_valid = true;
        m_localpixels = true;
    } else {
        m_pixels_valid = false;
        m_err = m_imagecache->geterror ();
    }

    return m_pixels_valid;
}
void
OSOReaderQuery::hint (string_view hintstring)
{
    if (! Strutil::parse_char (hintstring, '%'))
        return;
    if (Strutil::parse_prefix(hintstring, "meta{")) {
        // std::cerr << "  Metadata '" << hintstring << "'\n";
        Strutil::skip_whitespace (hintstring);
        std::string type = Strutil::parse_until (hintstring, ",}");
        Strutil::parse_char (hintstring, ',');
        std::string name = Strutil::parse_until (hintstring, ",}");
        Strutil::parse_char (hintstring, ',');
        // std::cerr << "    " << name << " : " << type << "\n";
        OSLQuery::Parameter p;
        p.name = name;
        p.type = TypeDesc (type.c_str());
        if (p.type.basetype == TypeDesc::STRING) {
            string_view val;
            while (Strutil::parse_string (hintstring, val)) {
                p.sdefault.push_back (ustring(val));
                if (Strutil::parse_char (hintstring, '}'))
                    break;
                Strutil::parse_char (hintstring, ',');
            }
        } else if (p.type.basetype == TypeDesc::INT) {
            int val;
            while (Strutil::parse_int (hintstring, val)) {
                p.idefault.push_back (val);
                Strutil::parse_char (hintstring, ',');
            }
        } else if (p.type.basetype == TypeDesc::FLOAT) {
            float val;
            while (Strutil::parse_float (hintstring, val)) {
                p.fdefault.push_back (val);
                Strutil::parse_char (hintstring, ',');
            }
        }
        Strutil::parse_char (hintstring, '}');
        if (m_reading_param) // Parameter metadata
            m_query.m_params[m_query.nparams()-1].metadata.push_back (p);
        else // global shader metadata
            m_query.m_meta.push_back (p);
        return;
    }
    if (m_reading_param && Strutil::parse_prefix(hintstring, "structfields{")) {
        OSLQuery::Parameter &param (m_query.m_params[m_query.nparams()-1]);
        string_view ident;
        while (1) {
            string_view ident = Strutil::parse_identifier (hintstring);
            if (ident.length()) {
                param.fields.push_back (ustring(ident));
                Strutil::parse_char (hintstring, ',');
            } else {
                break;
            }
        }
        Strutil::parse_char (hintstring, '}');
        return;
    }
    if (m_reading_param && Strutil::parse_prefix(hintstring, "struct{")) {
        string_view str;
        Strutil::parse_string (hintstring, str);
        m_query.m_params[m_query.nparams()-1].structname = str;
        Strutil::parse_char (hintstring, '}');
        return;
    }
    if (m_reading_param && Strutil::parse_prefix(hintstring, "initexpr")) {
        m_query.m_params[m_query.nparams()-1].validdefault = false;
        return;
    }

    // std::cerr << "Hint '" << hintstring << "'\n";
}