示例#1
0
MojoArchive *MojoArchive_newFromInput(MojoInput *_io, const char *origfname)
{
    int i;
    MojoArchive *retval = NULL;
    const char *ext = NULL;
    MojoInput *io = MojoInput_newCompressedStream(_io);
    if (io == NULL)
        io = _io;

    if (origfname != NULL)
    {
        ext = strrchr(origfname, '/');
        if (ext == NULL)
            ext = strchr(origfname, '.');
        else
            ext = strchr(ext+1, '.');
    } // if

    while (ext != NULL)
    {
        // Try for an exact match by filename extension.
        ext++;  // skip that '.'
        for (i = 0; i < STATICARRAYLEN(archives); i++)
        {
            const MojoArchiveType *arc = &archives[i];
            if (strcasecmp(ext, arc->ext) == 0)
                return arc->create(io);
        } // for
        ext = strchr(ext, '.');
    } // while

    // Try any that could be determined without the file extension...
    for (i = 0; i < STATICARRAYLEN(archives); i++)
    {
        const MojoArchiveType *arc = &archives[i];
        if ((arc->hasMagic) && ((retval = arc->create(io)) != NULL))
            return retval;
    } // for

    io->close(io);
    return NULL;  // nothing can handle this data.
} // MojoArchive_newFromInput
示例#2
0
static int MojoGui_stdio_readme(const char *name, const uint8 *_data,
                                size_t datalen, boolean can_back,
                                boolean can_fwd)
{
    const char *data = (const char *) _data;
    char buf[256];
    int retval = -1;
    boolean failed = true;

    // !!! FIXME: popen() isn't reliable.
    #if 0  //PLATFORM_UNIX
    const size_t namelen = strlen(name);
    const char *programs[] = { getenv("PAGER"), "more", "less -M", "less" };
    int i = 0;

    // flush streams, so output doesn't mingle with the popen()'d process.
    fflush(stdout);
    fflush(stderr);

    for (i = 0; i < STATICARRAYLEN(programs); i++)
    {
        const char *cmd = programs[i];
        if (cmd != NULL)
        {
            FILE *io = popen(cmd, "w");
            if (io != NULL)
            {
                failed = false;
                if (!failed) failed = (fwrite("\n", 1, 1, io) != 1);
                if (!failed) failed = (fwrite(name, namelen, 1, io) != 1);
                if (!failed) failed = (fwrite("\n", 1, 1, io) != 1);
                if (!failed) failed = (fwrite(data, datalen, 1, io) != 1);
                if (!failed) failed = (fwrite("\n", 1, 1, io) != 1);
                failed |= (pclose(io) != 0);  // call whether we failed or not.
                if (!failed)
                    break;  // it worked, we're done!
            } // if
        } // if
    } // for
    #endif // PLATFORM_UNIX

    if (failed)  // We're not Unix, or none of the pagers worked?
        dumb_pager(name, data, datalen);

    // Put up the "hit enter to continue (or 'back' to go back)" prompt,
    //  but only if there's an choice to be made here.
    if ((!can_back) || (readstr(NULL, buf, sizeof (buf), can_back, true) >= 0))
        retval = 1;

    return retval;
} // MojoGui_stdio_readme
示例#3
0
文件: dds.cpp 项目: fanqsh/vdrift
static int parse_dds(
	DDSHeader &header, const uint8 *&ptr, size_t &len,
	unsigned int &_glfmt, unsigned int &_miplevels)
{
    const uint32 pitchAndLinear = (DDSD_PITCH | DDSD_LINEARSIZE);
    uint32 width = 0;
    uint32 height = 0;
    uint32 calcSize = 0;
    uint32 calcSizeFlag = DDSD_LINEARSIZE;

    // Files start with magic value...
    if (readui32(ptr, len) != DDS_MAGIC)
        return 0;  // not a DDS file.

    // Then comes the DDS header...
    if (len < DDS_HEADERSIZE)
        return 0;

    header.dwSize = readui32(ptr, len);
    header.dwFlags = readui32(ptr, len);
    header.dwHeight = readui32(ptr, len);
    header.dwWidth = readui32(ptr, len);
    header.dwPitchOrLinearSize = readui32(ptr, len);
    header.dwDepth = readui32(ptr, len);
    header.dwMipMapCount = readui32(ptr, len);
    for (unsigned int i = 0; i < STATICARRAYLEN(header.dwReserved1); i++)
        header.dwReserved1[i] = readui32(ptr, len);
    header.ddspf.dwSize = readui32(ptr, len);
    header.ddspf.dwFlags = readui32(ptr, len);
    header.ddspf.dwFourCC = readui32(ptr, len);
    header.ddspf.dwRGBBitCount = readui32(ptr, len);
    header.ddspf.dwRBitMask = readui32(ptr, len);
    header.ddspf.dwGBitMask = readui32(ptr, len);
    header.ddspf.dwBBitMask = readui32(ptr, len);
    header.ddspf.dwABitMask = readui32(ptr, len);
    header.dwCaps = readui32(ptr, len);
    header.dwCaps2 = readui32(ptr, len);
    header.dwCaps3 = readui32(ptr, len);
    header.dwCaps4 = readui32(ptr, len);
    header.dwReserved2 = readui32(ptr, len);

    width = header.dwWidth;
    height = header.dwHeight;

    header.dwCaps &= ~DDSCAPS_ALPHA;  // we'll get this from the pixel format.

    if (header.dwSize != DDS_HEADERSIZE)   // header size must be 124.
        return 0;
    else if (header.ddspf.dwSize != DDS_PIXFMTSIZE)   // size must be 32.
        return 0;
    else if ((header.dwFlags & DDSD_REQ) != DDSD_REQ)  // must have these bits.
        return 0;
    else if ((header.dwCaps & DDSCAPS_TEXTURE) == 0)
        return 0;
    else if (header.dwCaps2 != 0)  // !!! FIXME (non-zero with other bits in dwCaps set)
        return 0;
    else if ((header.dwFlags & pitchAndLinear) == pitchAndLinear)
        return 0;  // can't specify both.

    _miplevels = (header.dwCaps & DDSCAPS_MIPMAP) ? header.dwMipMapCount : 1;

    if (header.ddspf.dwFlags & DDPF_FOURCC)
    {
        switch (header.ddspf.dwFourCC)
        {
            case FOURCC_DXT1:
                _glfmt = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
                calcSize = ((width ? ((width + 3) / 4) : 1) * 8) *
                           (height ? ((height + 3) / 4) : 1);
                break;
            case FOURCC_DXT3:
                _glfmt = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
                calcSize = ((width ? ((width + 3) / 4) : 1) * 16) *
                           (height ? ((height + 3) / 4) : 1);
                break;
            case FOURCC_DXT5:
                _glfmt = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
                calcSize = ((width ? ((width + 3) / 4) : 1) * 16) *
                           (height ? ((height + 3) / 4) : 1);
                break;

            // !!! FIXME: DX10 is an extended header, introduced by DirectX 10.
            //case FOURCC_DX10: do_something(); break;

            //case FOURCC_DXT2:  // premultiplied alpha unsupported.
            //case FOURCC_DXT4:  // premultiplied alpha unsupported.
            default:
                return 0;  // unsupported data format.
        } // switch
    } // if

    // no FourCC...uncompressed data.
    else if (header.ddspf.dwFlags & DDPF_RGB)
    {
        if ( (header.ddspf.dwRBitMask != 0x00FF0000) ||
             (header.ddspf.dwGBitMask != 0x0000FF00) ||
             (header.ddspf.dwBBitMask != 0x000000FF) )
            return 0;  // !!! FIXME: deal with this.

        if (header.ddspf.dwFlags & DDPF_ALPHAPIXELS)
        {
            if ( (header.ddspf.dwRGBBitCount != 32) ||
                 (header.ddspf.dwABitMask != 0xFF000000) )
                return 0;  // unsupported.
            _glfmt = GL_BGRA;
        } // if
        else
        {
            if (header.ddspf.dwRGBBitCount != 24)
                return 0;  // unsupported.
            _glfmt = GL_BGR;
        } // else

        calcSizeFlag = DDSD_PITCH;
        calcSize = ((width * header.ddspf.dwRGBBitCount) + 7) / 8;
    } // else if

    //else if (header.ddspf.dwFlags & DDPF_LUMINANCE)  // !!! FIXME
    //else if (header.ddspf.dwFlags & DDPF_YUV)  // !!! FIXME
    //else if (header.ddspf.dwFlags & DDPF_ALPHA)  // !!! FIXME
    else
    {
        return 0;  // unsupported data format.
    } // else if

    // no pitch or linear size? Calculate it.
    if ((header.dwFlags & pitchAndLinear) == 0)
    {
        if (!calcSizeFlag)
        {
            assert(0 && "should have caught this up above");
            return 0;  // uh oh.
        } // if

        header.dwPitchOrLinearSize = calcSize;
        header.dwFlags |= calcSizeFlag;
    } // if

    return 1;
} // parse_dds