status_t BlobCache::unflatten(void const* buffer, size_t size, int fds[],
        size_t count) {
    // All errors should result in the BlobCache being in an empty state.
    mCacheEntries.clear();

    if (count != 0) {
        ALOGE("unflatten: nonzero fd count: %d", count);
        return BAD_VALUE;
    }

    // Read the cache header
    if (size < sizeof(Header)) {
        ALOGE("unflatten: not enough room for cache header");
        return BAD_VALUE;
    }
    const Header* header = reinterpret_cast<const Header*>(buffer);
    if (header->mMagicNumber != blobCacheMagic) {
        ALOGE("unflatten: bad magic number: %d", header->mMagicNumber);
        return BAD_VALUE;
    }
    if (header->mBlobCacheVersion != blobCacheVersion ||
            header->mDeviceVersion != blobCacheDeviceVersion) {
        // We treat version mismatches as an empty cache.
        return OK;
    }

    // Read cache entries
    const uint8_t* byteBuffer = reinterpret_cast<const uint8_t*>(buffer);
    off_t byteOffset = align4(sizeof(Header));
    size_t numEntries = header->mNumEntries;
    for (size_t i = 0; i < numEntries; i++) {
        if (byteOffset + sizeof(EntryHeader) > size) {
            mCacheEntries.clear();
            ALOGE("unflatten: not enough room for cache entry headers");
            return BAD_VALUE;
        }

        const EntryHeader* eheader = reinterpret_cast<const EntryHeader*>(
                &byteBuffer[byteOffset]);
        size_t keySize = eheader->mKeySize;
        size_t valueSize = eheader->mValueSize;
        size_t entrySize = sizeof(EntryHeader) + keySize + valueSize;

        if (byteOffset + entrySize > size) {
            mCacheEntries.clear();
            ALOGE("unflatten: not enough room for cache entry headers");
            return BAD_VALUE;
        }

        const uint8_t* data = eheader->mData;
        set(data, keySize, data + keySize, valueSize);

        byteOffset += align4(entrySize);
    }

    return OK;
}
Beispiel #2
0
size_t BlobCache::getFlattenedSize() const {
    size_t size = align4(sizeof(Header) + PROPERTY_VALUE_MAX);
    for (const CacheEntry& e :  mCacheEntries) {
        std::shared_ptr<Blob> const& keyBlob = e.getKey();
        std::shared_ptr<Blob> const& valueBlob = e.getValue();
        size += align4(sizeof(EntryHeader) + keyBlob->getSize() + valueBlob->getSize());
    }
    return size;
}
Beispiel #3
0
int BlobCache::unflatten(void const* buffer, size_t size) {
    // All errors should result in the BlobCache being in an empty state.
    mCacheEntries.clear();

    // Read the cache header
    if (size < sizeof(Header)) {
        ALOGE("unflatten: not enough room for cache header");
        return -EINVAL;
    }
    const Header* header = reinterpret_cast<const Header*>(buffer);
    if (header->mMagicNumber != blobCacheMagic) {
        ALOGE("unflatten: bad magic number: %" PRIu32, header->mMagicNumber);
        return -EINVAL;
    }
    char buildId[PROPERTY_VALUE_MAX];
    int len = property_get("ro.build.id", buildId, "");
    if (header->mBlobCacheVersion != blobCacheVersion ||
            header->mDeviceVersion != blobCacheDeviceVersion ||
            len != header->mBuildIdLength ||
            strncmp(buildId, header->mBuildId, len)) {
        // We treat version mismatches as an empty cache.
        return 0;
    }

    // Read cache entries
    const uint8_t* byteBuffer = reinterpret_cast<const uint8_t*>(buffer);
    off_t byteOffset = align4(sizeof(Header) + header->mBuildIdLength);
    size_t numEntries = header->mNumEntries;
    for (size_t i = 0; i < numEntries; i++) {
        if (byteOffset + sizeof(EntryHeader) > size) {
            mCacheEntries.clear();
            ALOGE("unflatten: not enough room for cache entry header");
            return -EINVAL;
        }

        const EntryHeader* eheader = reinterpret_cast<const EntryHeader*>(
                &byteBuffer[byteOffset]);
        size_t keySize = eheader->mKeySize;
        size_t valueSize = eheader->mValueSize;
        size_t entrySize = sizeof(EntryHeader) + keySize + valueSize;

        size_t totalSize = align4(entrySize);
        if (byteOffset + totalSize > size) {
            mCacheEntries.clear();
            ALOGE("unflatten: not enough room for cache entry");
            return -EINVAL;
        }

        const uint8_t* data = eheader->mData;
        set(data, keySize, data + keySize, valueSize);

        byteOffset += totalSize;
    }

    return 0;
}
status_t BlobCache::flatten(void* buffer, size_t size) const {
    // Write the cache header
    if (size < sizeof(Header)) {
        ALOGE("flatten: not enough room for cache header");
        return BAD_VALUE;
    }
    Header* header = reinterpret_cast<Header*>(buffer);
    header->mMagicNumber = blobCacheMagic;
    header->mBlobCacheVersion = blobCacheVersion;
    header->mDeviceVersion = blobCacheDeviceVersion;
    header->mNumEntries = mCacheEntries.size();
    char buildId[PROPERTY_VALUE_MAX];
    header->mBuildIdLength = property_get("ro.build.id", buildId, "");
    memcpy(header->mBuildId, buildId, header->mBuildIdLength);

    // Write cache entries
    uint8_t* byteBuffer = reinterpret_cast<uint8_t*>(buffer);
    off_t byteOffset = align4(sizeof(Header) + header->mBuildIdLength);
    for (size_t i = 0; i < mCacheEntries.size(); i++) {
        const CacheEntry& e(mCacheEntries[i]);
        sp<Blob> keyBlob = e.getKey();
        sp<Blob> valueBlob = e.getValue();
        size_t keySize = keyBlob->getSize();
        size_t valueSize = valueBlob->getSize();

        size_t entrySize = sizeof(EntryHeader) + keySize + valueSize;
        size_t totalSize = align4(entrySize);
        if (byteOffset + totalSize > size) {
            ALOGE("flatten: not enough room for cache entries");
            return BAD_VALUE;
        }

        EntryHeader* eheader = reinterpret_cast<EntryHeader*>(
            &byteBuffer[byteOffset]);
        eheader->mKeySize = keySize;
        eheader->mValueSize = valueSize;

        memcpy(eheader->mData, keyBlob->getData(), keySize);
        memcpy(eheader->mData + keySize, valueBlob->getData(), valueSize);

        if (totalSize > entrySize) {
            // We have padding bytes. Those will get written to storage, and contribute to the CRC,
            // so make sure we zero-them to have reproducible results.
            memset(eheader->mData + keySize + valueSize, 0, totalSize - entrySize);
        }

        byteOffset += totalSize;
    }

    return OK;
}
Beispiel #5
0
void* mm_realloc(void* ptr, size_t size)
{
#ifdef MM_USE_STUBS
    return realloc(ptr, size);
#else
    if(size==0){
        free(ptr);
        return ptr;
    }
    if(!ptr)
        return malloc(size);
    t_block last;
    t_block b = valid_addr(ptr,&last);
    if(!b)
        return ptr;
    size_t s = align4(size);
    if(b->size >= s){
        if(b->size > s+BLOCK_SIZE+4)
            split_block(b,s);
        return ptr;
    }
    void *new = malloc(s);
    if(!new)
        return NULL;
    size_t i,s4,*sp,*newp;
    s4=s/(sizeof(size_t));
    sp=(size_t*)(p);
    newp=(size_t*)(new);
    for(i=0;i<s4;i++)
        newp[i]=sp[i];
    free(ptr);
    return new;
    //#error Not implemented.
#endif
}
Beispiel #6
0
void* mm_malloc(size_t size)
{
#ifdef MM_USE_STUBS
    return calloc(1, size);
#else
    s_block_ptr block, last;

    size_t s;

    s = align4(size);

    if(foot){
        last = foot;
        block = find_block(last, s);
        if(block){
            if((block->size - s) >= (BLOCK_SIZE + 4)) split_block(block, s);
            block->free = 0;
        }
        else{
            block = extend_heap(last, s);
            if(!block) return NULL;
        }
    }
    else{
        block = extend_heap(NULL, s);
        if(!block) return NULL;
        foot = block;
    }
    return block->data;
    //#error Not implemented.
#endif
}
status_t BlobCache::flatten(void* buffer, size_t size, int fds[], size_t count)
        const {
    if (count != 0) {
        ALOGE("flatten: nonzero fd count: %d", count);
        return BAD_VALUE;
    }

    // Write the cache header
    if (size < sizeof(Header)) {
        ALOGE("flatten: not enough room for cache header");
        return BAD_VALUE;
    }
    Header* header = reinterpret_cast<Header*>(buffer);
    header->mMagicNumber = blobCacheMagic;
    header->mBlobCacheVersion = blobCacheVersion;
    header->mDeviceVersion = blobCacheDeviceVersion;
    header->mNumEntries = mCacheEntries.size();

    // Write cache entries
    uint8_t* byteBuffer = reinterpret_cast<uint8_t*>(buffer);
    off_t byteOffset = align4(sizeof(Header));
    for (size_t i = 0; i < mCacheEntries.size(); i++) {
        const CacheEntry& e(mCacheEntries[i]);
        sp<Blob> keyBlob = e.getKey();
        sp<Blob> valueBlob = e.getValue();
        size_t keySize = keyBlob->getSize();
        size_t valueSize = valueBlob->getSize();

        size_t entrySize = sizeof(EntryHeader) + keySize + valueSize;
        if (byteOffset + entrySize > size) {
            ALOGE("flatten: not enough room for cache entries");
            return BAD_VALUE;
        }

        EntryHeader* eheader = reinterpret_cast<EntryHeader*>(
            &byteBuffer[byteOffset]);
        eheader->mKeySize = keySize;
        eheader->mValueSize = valueSize;

        memcpy(eheader->mData, keyBlob->getData(), keySize);
        memcpy(eheader->mData + keySize, valueBlob->getData(), valueSize);

        byteOffset += align4(entrySize);
    }

    return OK;
}
Beispiel #8
0
/*! A strdup version that aligns on 4 bytes. To avoid warning from valgrind */
static inline char * strdup4(char *str) 
{
    char *dup;
    int len;
    len = align4(strlen(str)+1);
    if ((dup = malloc(len)) == NULL)
	return NULL;
    strncpy(dup, str, len);
    return dup;
}
Beispiel #9
0
void QPAGenerator::writeHeader()
{
    QFontEngineQPA::Header header;

    header.magic[0] = 'Q';
    header.magic[1] = 'P';
    header.magic[2] = 'F';
    header.magic[3] = '2';
    header.lock = 1;
    header.majorVersion = QFontEngineQPA::CurrentMajorVersion;
    header.minorVersion = QFontEngineQPA::CurrentMinorVersion;
    header.dataSize = 0;
    dev->write((const char *)&header, sizeof(header));

    writeTaggedString(QFontEngineQPA::Tag_FontName, fe->fontDef.family.toUtf8());

    QFontEngine::FaceId face = fe->faceId();
    writeTaggedString(QFontEngineQPA::Tag_FileName, face.filename);
    writeTaggedUInt32(QFontEngineQPA::Tag_FileIndex, face.index);

    {
        uchar data[4];
        uint len = 4;
        bool ok = fe->getSfntTableData(MAKE_TAG('h', 'e', 'a', 'd'), data, &len);
        if (ok) {
            const quint32 revision = qFromBigEndian<quint32>(data);
            writeTaggedUInt32(QFontEngineQPA::Tag_FontRevision, revision);
        }
    }

    writeTaggedQFixed(QFontEngineQPA::Tag_Ascent, fe->ascent());
    writeTaggedQFixed(QFontEngineQPA::Tag_Descent, fe->descent());
    writeTaggedQFixed(QFontEngineQPA::Tag_Leading, fe->leading());
    writeTaggedQFixed(QFontEngineQPA::Tag_XHeight, fe->xHeight());
    writeTaggedQFixed(QFontEngineQPA::Tag_AverageCharWidth, fe->averageCharWidth());
    writeTaggedQFixed(QFontEngineQPA::Tag_MaxCharWidth, QFixed::fromReal(fe->maxCharWidth()));
    writeTaggedQFixed(QFontEngineQPA::Tag_LineThickness, fe->lineThickness());
    writeTaggedQFixed(QFontEngineQPA::Tag_MinLeftBearing, QFixed::fromReal(fe->minLeftBearing()));
    writeTaggedQFixed(QFontEngineQPA::Tag_MinRightBearing, QFixed::fromReal(fe->minRightBearing()));
    writeTaggedQFixed(QFontEngineQPA::Tag_UnderlinePosition, fe->underlinePosition());
    writeTaggedUInt8(QFontEngineQPA::Tag_PixelSize, fe->fontDef.pixelSize);
    writeTaggedUInt8(QFontEngineQPA::Tag_Weight, fe->fontDef.weight);
    writeTaggedUInt8(QFontEngineQPA::Tag_Style, fe->fontDef.style);

    writeTaggedUInt8(QFontEngineQPA::Tag_GlyphFormat, QFontEngineQPA::AlphamapGlyphs);

    writeTaggedString(QFontEngineQPA::Tag_EndOfHeader, QByteArray());
    align4();

    const quint64 size = dev->pos();
    header.dataSize = qToBigEndian<quint16>(size - sizeof(header));
    dev->seek(0);
    dev->write((const char *)&header, sizeof(header));
    dev->seek(size);
}
Beispiel #10
0
void QPF::addHeader(QFontEngine *fontEngine)
{
    QFontEngineQPF::Header *header = reinterpret_cast<QFontEngineQPF::Header *>(addBytes(sizeof(QFontEngineQPF::Header)));

    header->magic[0] = 'Q';
    header->magic[1] = 'P';
    header->magic[2] = 'F';
    header->magic[3] = '2';
    if (options & RenderGlyphs)
        header->lock = 0xffffffff;
    else
        header->lock = 0;
    header->majorVersion = QFontEngineQPF::CurrentMajorVersion;
    header->minorVersion = QFontEngineQPF::CurrentMinorVersion;
    header->dataSize = 0;
    int oldSize = qpf.size();

    addTaggedString(QFontEngineQPF::Tag_FontName, fontEngine->fontDef.family.toUtf8());

    QFontEngine::FaceId face = fontEngine->faceId();
    addTaggedString(QFontEngineQPF::Tag_FileName, face.filename);
    addTaggedUInt32(QFontEngineQPF::Tag_FileIndex, face.index);

    {
        const QByteArray head = fontEngine->getSfntTable(MAKE_TAG('h', 'e', 'a', 'd'));
        const quint32 revision = qFromBigEndian<quint32>(reinterpret_cast<const uchar *>(head.constData()) + 4);
        addTaggedUInt32(QFontEngineQPF::Tag_FontRevision, revision);
    }

    addTaggedQFixed(QFontEngineQPF::Tag_Ascent, fontEngine->ascent());
    addTaggedQFixed(QFontEngineQPF::Tag_Descent, fontEngine->descent());
    addTaggedQFixed(QFontEngineQPF::Tag_Leading, fontEngine->leading());
    addTaggedQFixed(QFontEngineQPF::Tag_XHeight, fontEngine->xHeight());
    addTaggedQFixed(QFontEngineQPF::Tag_AverageCharWidth, fontEngine->averageCharWidth());
    addTaggedQFixed(QFontEngineQPF::Tag_MaxCharWidth, QFixed::fromReal(fontEngine->maxCharWidth()));
    addTaggedQFixed(QFontEngineQPF::Tag_LineThickness, fontEngine->lineThickness());
    addTaggedQFixed(QFontEngineQPF::Tag_MinLeftBearing, QFixed::fromReal(fontEngine->minLeftBearing()));
    addTaggedQFixed(QFontEngineQPF::Tag_MinRightBearing, QFixed::fromReal(fontEngine->minRightBearing()));
    addTaggedQFixed(QFontEngineQPF::Tag_UnderlinePosition, fontEngine->underlinePosition());
    addTaggedUInt8(QFontEngineQPF::Tag_PixelSize, fontEngine->fontDef.pixelSize);
    addTaggedUInt8(QFontEngineQPF::Tag_Weight, fontEngine->fontDef.weight);
    addTaggedUInt8(QFontEngineQPF::Tag_Style, fontEngine->fontDef.style);

    QByteArray writingSystemBitField = getWritingSystems(fontEngine);
    if (!writingSystemBitField.isEmpty())
        addTaggedString(QFontEngineQPF::Tag_WritingSystems, writingSystemBitField);

    addTaggedUInt8(QFontEngineQPF::Tag_GlyphFormat, QFontEngineQPF::AlphamapGlyphs);

    addTaggedString(QFontEngineQPF::Tag_EndOfHeader, QByteArray());
    align4();
    header = reinterpret_cast<QFontEngineQPF::Header *>(qpf.data());
    header->dataSize = qToBigEndian<quint16>(qpf.size() - oldSize);
}
Beispiel #11
0
    static void dump_png24_impl(
        png_struct * ppng, png_info * pinfo,
        const uint8_t * data, const size_t width, const size_t height, const size_t rowsize,
        const bool bgr, IsOk is_ok
    ) {
        assert(align4(rowsize) == rowsize);

        png_set_IHDR(ppng, pinfo, width, height, 8,
                    PNG_COLOR_TYPE_RGB,
                    PNG_INTERLACE_NONE,
                    PNG_COMPRESSION_TYPE_BASE,
                    PNG_FILTER_TYPE_BASE);
        png_write_info(ppng, pinfo);

        // send image buffer to file, one pixel row at once
        const uint8_t * row = data;

        if (bgr) {
            uint8_t bgrtmp[8192*4];
            for (size_t k = 0 ; k < height && is_ok(); ++k) {
                const uint8_t * s = row;
                uint8_t * t = bgrtmp;
                uint8_t * e = t + (width / 4) * 12;
                for (; t < e; s += 12, t += 12){
                    t[0] = s[2];
                    t[1] = s[1];
                    t[2] = s[0];

                    t[3] = s[5];
                    t[4] = s[4];
                    t[5] = s[3];

                    t[6] = s[8];
                    t[7] = s[7];
                    t[8] = s[6];

                    t[9] = s[11];
                    t[10] = s[10];
                    t[11] = s[9];
                }
                png_write_row(ppng, const_cast<unsigned char*>(bgrtmp));
                row += rowsize;
            }
        }
        else {
            for (size_t k = 0 ; k < height && is_ok(); ++k) {
                png_write_row(ppng, const_cast<unsigned char*>(row));
                row += rowsize;
            }
        }
    }
Beispiel #12
0
void* mymalloc(size_t size)
{
  t_block b, last;
  size = align4(size);

  if (base) {
    b = find_block(size, &last);
    if (b) {
      if (b->size - size >=  BLOCK_SIZE + 4) {
        split_block(b, size);
      }
      b->free = 0;
    } else {
      b = extend_heap(last, size);
    }
  } else {
    b = extend_heap(NULL, size);
    if (!b) base = b;
  }

  return b ? b->data : NULL;
}
Beispiel #13
0
static inline uint32_t aligned_size(int width, int height, uint8_t bpp)
{
    return align4(width) * height * ((bpp<=8)?1:(bpp<=16)?2:4);
}
Beispiel #14
0
 //==============================================================================
 inline int datasize() const noexcept
 //==============================================================================
 {
     return align4(nbbytes(this->width) * this->height);
 }
Beispiel #15
0
static int  jz_lcd_hw_init(vidinfo_t *vid)
{
	struct jz_fb_info *fbi = &vid->jz_fb;
	unsigned int val = 0;
	unsigned int pclk;
	unsigned int stnH;
#if defined(CONFIG_MIPS_JZ4740)
	int pll_div;
#endif

	/* Setting Control register */
	switch (jzfb.bpp) {
	case 1:
		val |= LCD_CTRL_BPP_1;
		break;
	case 2:
		val |= LCD_CTRL_BPP_2;
		break;
	case 4:
		val |= LCD_CTRL_BPP_4;
		break;
	case 8:
		val |= LCD_CTRL_BPP_8;
		break;
	case 15:
		val |= LCD_CTRL_RGB555;
	case 16:
		val |= LCD_CTRL_BPP_16;
		break;
#if defined(CONFIG_MIPS_JZ4740)
	case 17 ... 32:
		val |= LCD_CTRL_BPP_18_24;	/* target is 4bytes/pixel */
		break;
#endif
	default:
		printf("jz_lcd.c The BPP %d is not supported\n", jzfb.bpp);
		val |= LCD_CTRL_BPP_16;
		break;
	}

	switch (jzfb.cfg & MODE_MASK) {
	case MODE_STN_MONO_DUAL:
	case MODE_STN_COLOR_DUAL:
	case MODE_STN_MONO_SINGLE:
	case MODE_STN_COLOR_SINGLE:
		switch (jzfb.bpp) {
		case 1:
			/* val |= LCD_CTRL_PEDN; */
		case 2:
			val |= LCD_CTRL_FRC_2;
			break;
		case 4:
			val |= LCD_CTRL_FRC_4;
			break;
		case 8:
		default:
			val |= LCD_CTRL_FRC_16;
			break;
		}
		break;
	}

	val |= LCD_CTRL_BST_16;		/* Burst Length is 16WORD=64Byte */
	val |= LCD_CTRL_OFUP;		/* OutFIFO underrun protect */

	switch (jzfb.cfg & MODE_MASK) {
	case MODE_STN_MONO_DUAL:
	case MODE_STN_COLOR_DUAL:
	case MODE_STN_MONO_SINGLE:
	case MODE_STN_COLOR_SINGLE:
		switch (jzfb.cfg & STN_DAT_PINMASK) {
#define align2(n) (n)=((((n)+1)>>1)<<1)
#define align4(n) (n)=((((n)+3)>>2)<<2)
#define align8(n) (n)=((((n)+7)>>3)<<3)
		case STN_DAT_PIN1:
			/* Do not adjust the hori-param value. */
			break;
		case STN_DAT_PIN2:
			align2(jzfb.hsw);
			align2(jzfb.elw);
			align2(jzfb.blw);
			break;
		case STN_DAT_PIN4:
			align4(jzfb.hsw);
			align4(jzfb.elw);
			align4(jzfb.blw);
			break;
		case STN_DAT_PIN8:
			align8(jzfb.hsw);
			align8(jzfb.elw);
			align8(jzfb.blw);
			break;
		}
		break;
	}

	REG_LCD_CTRL = val;

	switch (jzfb.cfg & MODE_MASK) {
	case MODE_STN_MONO_DUAL:
	case MODE_STN_COLOR_DUAL:
	case MODE_STN_MONO_SINGLE:
	case MODE_STN_COLOR_SINGLE:
		if (((jzfb.cfg & MODE_MASK) == MODE_STN_MONO_DUAL) ||
		    ((jzfb.cfg & MODE_MASK) == MODE_STN_COLOR_DUAL))
			stnH = jzfb.h >> 1;
		else
			stnH = jzfb.h;

		REG_LCD_VSYNC = (0 << 16) | jzfb.vsw;
		REG_LCD_HSYNC = ((jzfb.blw+jzfb.w) << 16) | (jzfb.blw+jzfb.w+jzfb.hsw);

		/* Screen setting */
		REG_LCD_VAT = ((jzfb.blw + jzfb.w + jzfb.hsw + jzfb.elw) << 16) | (stnH + jzfb.vsw + jzfb.bfw + jzfb.efw);
		REG_LCD_DAH = (jzfb.blw << 16) | (jzfb.blw + jzfb.w);
		REG_LCD_DAV = (0 << 16) | (stnH);

		/* AC BIAs signal */
		REG_LCD_PS = (0 << 16) | (stnH+jzfb.vsw+jzfb.efw+jzfb.bfw);

		break;

	case MODE_TFT_GEN:
	case MODE_TFT_SHARP:
	case MODE_TFT_CASIO:
	case MODE_TFT_SAMSUNG:
	case MODE_8BIT_SERIAL_TFT:
	case MODE_TFT_18BIT:
		REG_LCD_VSYNC = (0 << 16) | jzfb.vsw;
		REG_LCD_HSYNC = (0 << 16) | jzfb.hsw;
#if defined(CONFIG_JZLCD_INNOLUX_AT080TN42)
		REG_LCD_DAV = (0 << 16) | ( jzfb.h );
#else
		REG_LCD_DAV =((jzfb.vsw+jzfb.bfw) << 16) | (jzfb.vsw +jzfb.bfw+jzfb.h);
#endif /*#if defined(CONFIG_JZLCD_INNOLUX_AT080TN42)*/
		REG_LCD_DAH = ((jzfb.hsw + jzfb.blw) << 16) | (jzfb.hsw + jzfb.blw + jzfb.w );
		REG_LCD_VAT = (((jzfb.blw + jzfb.w + jzfb.elw + jzfb.hsw)) << 16) \
			| (jzfb.vsw + jzfb.bfw + jzfb.h + jzfb.efw);
		break;
	}
Beispiel #16
0
void model_draw(const shader_t *s, GLuint utrans, GLuint uquats,
                const GLuint *texture, const uint32_t *mdl,
                int anim_id, double frame, const float *teamcolor,
                const float *color, uint16_t tex_over)
{
    /* assumes valid model data */
    uint8_t ngeo, teamcolor_end, nbone, nanim;
    const uint8_t *p, *tr, *qt;

    const chunkinfo_t *ck;
    const anim_t *anim;
    const bone_t *b;
    vec3 trans, ptrans;
    vec4 rot, prot;
    int vis, i, offset, tex;

    vec3 rtrans[maxbones];
    vec4 rotation[maxbones];

    /* parse header */
    p = (const uint8_t*)mdl;
    ngeo = p[0];
    teamcolor_end = p[1];
    nbone = p[2];
    nanim = p[3];

    anim = (const anim_t*)&p[4];
    ck = (const chunkinfo_t*)&anim[nanim];
    p = (const uint8_t*)&ck[ngeo];
    anim += anim_id;

    vis = anim->vis;
    frame = frame * anim->frames;

    /* calculate transformations for frame */
    i = 0;
    do {
        b = (const bone_t*)p;
        tr = (const uint8_t*)&b[1];
        qt = tr + nanim;
        p = qt + nanim;
        p = align4(p);

        get_trans(&trans, p, tr, anim_id, frame);
        p += b->keyframes[0] * sizeof(keyframe_t);

        get_rot(&rot, p, qt, anim_id, frame);
        p += b->keyframes[1] * sizeof(keyframe4_t);

        if(b->parent < 0) {
            ptrans = vec3(0.0, 0.0, 0.0);
            prot = vec4(0.0, 0.0, 0.0, 1.0);
        } else {
            ptrans = rtrans[b->parent];
            prot = rotation[b->parent];
        }

        rotation[i] = mul4(rot, prot);
        trans = add3(ptrans, qrot3(add3(b->pivot, trans), prot));
        rtrans[i] = add3(qrot3(neg3(b->pivot), rotation[i]), trans);
    } while (++i < nbone);

    /* load transformations */
    glUniform4fv(uquats, nbone, (float*)rotation);
    glUniform3fv(utrans, nbone, (float*)rtrans);

    //GLuint test;
    //glGenBuffers(1, &test);
    //
    //glBufferData(GL_ELEMENT_ARRAY_BUFFER, ck[ngeo - 1].index, indices, GL_STATIC_DRAW);

    /* draw visible vertices */
    i = 0;
    offset = 0;
    tex = 0xFFFF;
    glUniform4fv(s->k, 1, teamcolor);
    glUniform4fv(s->samp, 1, color);
    do {
        if(i == teamcolor_end)
            glUniform4fv(s->k, 1, transparency);

        if((vis & (1 << i))) {
            if (tex_over != 0xFFFF) {
                glBindTexture(GL_TEXTURE_2D, tex_over == 0xFFFE ? 0 : texture[tex_over]);
            } else if (ck[i].texture != tex) {
                tex = ck[i].texture;
                glBindTexture(GL_TEXTURE_2D, texture[tex]);
            }

            glDrawElements(GL_TRIANGLES, ck[i].index - offset, GL_UNSIGNED_SHORT, (void*)(size_t)offset);
        }
        offset = ck[i].index;
    } while(++i != ngeo);

    //glDeleteBuffers(1, &test);
}
Beispiel #17
0
/*---------------------------------------------------------------------------*/
int
elfloader_load(char* filename, char* fltfile)
{
  struct elf32_ehdr ehdr;
  struct elf32_shdr shdr;
  struct elf32_shdr strtable;
  unsigned int strs;
  unsigned int shdrptr;
  unsigned int nameptr;
  char name[12];
  
  int i;
  unsigned short shdrnum, shdrsize;

  int ret;

  /* Ensure that we have a correct and compatible ELF header. */
  ret = b_seek_read( 0, (char *)&ehdr, sizeof(ehdr));
  if (ret != sizeof(ehdr)) return ELFFLT_INPUT_ERROR;

  if(memcmp(ehdr.e_ident, elf_magic_header, sizeof(elf_magic_header)) != 0) {
    	PRINTERR(stderr, "ELF header problems\n");
    return ELFFLT_BAD_ELF_HEADER;
  }

  if ( FLAG_VERBOSE )
    	printf ("Grab section header\n");

  // Grab the section header.
  shdrptr = ehdr.e_shoff;
  ret = b_seek_read( shdrptr, (char *)&shdr, sizeof(shdr));
  if (ret != sizeof(shdr)) return ELFFLT_INPUT_ERROR;
  
  shdrsize = ehdr.e_shentsize;
  shdrnum = ehdr.e_shnum;

  if ( FLAG_VERBOSE )
    	printf ("Grab string table section\n");

  // Grab the string table section for the names of the sections. 
  ret = b_seek_read( ehdr.e_shoff + shdrsize * ehdr.e_shstrndx,
                             (char *)&strtable, sizeof(strtable));
  if (ret != sizeof(strtable)) return ELFFLT_INPUT_ERROR;
  strs = strtable.sh_offset;

  /* Parse segments headers to releavant_section entries.
		.text = actual code from the ELF file
		.data = initialized data
		.rodata = contains read-only data
		.bss = segment holds the size of the unitialized data segment
		.rel.text, .rel.data = relocation information for the contents 
					of the ".text" and ".data" segments, respectively.
		.symtab = symbol table for this file
		.strtab = points to the actual string names used by the symbol table.
  */


  // Zero size is indicator of unitialized (not found) section
  text.size = text.relasize = data.size = data.relasize =
    rodata.size = rodata.relasize = symtabsize = strtabsize = 0;

  bss.number = data.number = rodata.number = text.number = -1;
                
  shdrptr = ehdr.e_shoff;
  for(i = 0; i < shdrnum; ++i) {

    ret = b_seek_read( shdrptr, (char *)&shdr, sizeof(shdr));
	DEBUGPRINTF("==shdrptr=0x%x, sizeof=%d; size=0x%x\n",shdrptr,sizeof(shdr),shdrsize );
    if (ret != sizeof(shdr)) { PRINTERR(stderr, "input error at %s:%d :loaded%d",__FILE__,__LINE__,ret);return ELFFLT_INPUT_ERROR;}
    
    /* The name of the section is contained in the strings table. */
    nameptr = strs + shdr.sh_name;
	DEBUGPRINTF("==nameptr=%x(%x+%x), size=%d\n",nameptr,strs,shdr.sh_name,sizeof(name) );
    ret = b_seek_read( nameptr, name, sizeof(name));
    if (ret != sizeof(name)) {PRINTERR(stderr, "input error at %s:%d",__FILE__,__LINE__); return ELFFLT_INPUT_ERROR;}

	DEBUGPRINTF("==shdrptr=0x%x, sizeof=%d; size=0x%x\n",shdrptr,sizeof(shdr),shdrsize );
	if ( FLAG_DUMP_SECTIONS )
		printf ("Section #%d: %-15s [section header 0x%x, offset=0x%x, size %d, vma=0x%x]\n",i,name,shdrptr,
													shdr.sh_offset,shdr.sh_size, shdr.sh_addr);

    if(strncmp(name, ".text", 5) == 0) {
      text.number = i;
      text.offset = shdr.sh_offset;
      text.size = shdr.sh_size;
	  text.base_addr = shdr.sh_addr;
    } else if(strncmp(name, ".rel.text", 9) == 0) {
      text.relaoff = shdr.sh_offset;
      text.relasize = shdr.sh_size;
    } else if(strncmp(name, ".data", 5) == 0) {
      data.number = i;
      data.offset = shdr.sh_offset;
      data.size = shdr.sh_size;
	  data.base_addr = shdr.sh_addr;
    } else if(strncmp(name, ".rodata", 7) == 0) {
      rodata.number = i;
      rodata.offset = shdr.sh_offset;
      rodata.size = shdr.sh_size;
	  rodata.base_addr = shdr.sh_addr;
    } else if(strncmp(name, ".rel.rodata", 11) == 0) {
      rodata.relaoff = shdr.sh_offset;
      rodata.relasize = shdr.sh_size;
    } else if(strncmp(name, ".rel.data", 9) == 0) {
      data.relaoff = shdr.sh_offset;
      data.relasize = shdr.sh_size;
    } else if(strncmp(name, ".rela.", 6) == 0) {
      PRINTERR(stderr,"RELA relocs are not supported.");
      return ELFFLT_INPUT_ERROR;
    } else if(strncmp(name, ".symtab", 7) == 0) {
      symtaboff = shdr.sh_offset;
      symtabsize = shdr.sh_size;
    } else if(strncmp(name, ".strtab", 7) == 0) {
      strtaboff = shdr.sh_offset;
      strtabsize = shdr.sh_size;
    } else if(strncmp(name, ".bss", 4) == 0) {
      bss.size = shdr.sh_size;
      bss.number = i;
      bss.offset = 0;
    }

    shdrptr += shdrsize;
  }

  if(symtabsize == 0) {
    PRINTERR(stderr,"No symbol table found.");
    return ELFFLT_NO_SYMTAB;
  }
  if(strtabsize == 0) {
    PRINTERR(stderr,"No strings table found.");
    return ELFFLT_NO_STRTAB;
  }
  if(text.size == 0) {
    PRINTERR(stderr, "No .text segment found.");
  	return ELFFLT_NO_TEXT;
  }

  if ( (text.relasize + rodata.relasize+ data.relasize) <=0 ) {
      PRINTERR(stderr,"Found no reloc sections. Please link with -r -d options.\n");
      return ELFFLT_UNHANDLED_RELOC;
  }

  if (bss.size) {
    bss.address = (char *)malloc(bss.size);
    if (!bss.address) return ELFFLT_OUTPUT_ERROR;
  }
  if (data.size) {
    data.address = (char *)malloc(data.size);
    if (!data.address) return ELFFLT_OUTPUT_ERROR;
  }
  if (text.size) {
    text.address = (char *)malloc(text.size);
    if (!text.address) return ELFFLT_OUTPUT_ERROR;
  }
  if (rodata.size) {
    rodata.address =  (char *)malloc(rodata.size);
    if (!rodata.address) return ELFFLT_OUTPUT_ERROR;
  }

  rodata.name=".rodata";
  bss.name=".bss";
  text.name=".text";
  data.name=".data";



  b_seek_read(text.offset, text.address, text.size);
  b_seek_read(data.offset, data.address, data.size);
  b_seek_read(rodata.offset, rodata.address, rodata.size);

  if ( FLAG_DUMP_SOURCE ) {
    dump_section( text.name, (unsigned char *)text.address, text.size );
    dump_section( data.name, (unsigned char *)data.address, data.size );
    dump_section( rodata.name, (unsigned char *)rodata.address, rodata.size );
  }

  if ( FLAG_DUMP_SYMBOLS ) {
    dump_symtable();
  }

  if ( FLAG_DUMP_SYMBOLS || FLAG_DUMP_SOURCE || FLAG_VERBOSE )
	 printf("\n\n");

  if ( FLAG_VERBOSE )
   	 printf ("Prepare flat\n");

  int div0hack_size = sizeof(div0_arm);

  int flatmainsize = sizeof(struct flat_hdr)+text.size+div0hack_size+data.size+rodata.size+bss.size;  
  int flatrelocsize = text.relasize+rodata.relasize+data.relasize;


  // Take to account aligning to int32 each section  
  flatmainsize += align4(text.size) + align4(data.size) + align4(rodata.size) + align4(bss.size);
  
  flat_buf=malloc( flatmainsize+flatrelocsize );      
  if ( !flat_buf) { PRINTERR(stderr, "fail to malloc flat buf\n"); return ELFFLT_OUTPUT_ERROR;}
  memset(flat_buf, 0, flatmainsize+flatrelocsize);
  
  //import is subset of full reloc list, so same count is enough
  // but apply multiplier to take into account difference between sizeofs
  flat_import_buf=malloc( flatrelocsize* sizeof(import_record_t)/sizeof(reloc_record_t) );      		
  if ( !flat_import_buf) { PRINTERR(stderr, "fail to malloc flat import buf\n"); return ELFFLT_OUTPUT_ERROR;}
  memset(flat_import_buf, 0, flatrelocsize);

  // Fill flat with sections aligned to int32

  flat = (struct flat_hdr*) flat_buf;

  if ( FLAG_VERBOSE )
      printf(">>elf2flt: load segments\n");
  int offset=sizeof(struct flat_hdr);
  text.flat_offset = offset;
  memcpy( flat_buf+offset, text.address, text.size );
  DEBUGPRINTF("load .txt to %x (%x->%x)\n",offset,text.size,text.size+align4(text.size));
  offset+=text.size+div0hack_size+align4(text.size);


  rodata.flat_offset = offset;
  DEBUGPRINTF("load .rodata to %x (%x->%x)\n",offset,rodata.size,rodata.size+align4(rodata.size));
  memcpy( flat_buf+offset, rodata.address, rodata.size );
  offset+=rodata.size+align4(rodata.size);

  data.flat_offset = offset;
  DEBUGPRINTF("load .data to %x (%x->%x)\n",offset,data.size,data.size+align4(data.size));
  memcpy( flat_buf+offset, data.address, data.size );
  offset+=data.size+align4(data.size);

  bss.flat_offset = offset;
  DEBUGPRINTF(".bss to %x (%x->%x)\n",offset,bss.size,bss.size+align4(bss.size));
  DEBUGPRINTF("result=%x\n",  flatmainsize);

  // Initialize flat headers
  memcpy(flat->magic, FLAT_MAGIC_NUMBER, sizeof(flat->magic));       // Set magic (CHDK_FLAT)
  flat->rev = FLAT_VERSION;
  flat->entry = text.flat_offset;
  flat->data_start = rodata.flat_offset;
  flat->bss_start = bss.flat_offset;  
  flat->reloc_start = flatmainsize;
  flat_reloc_count = 0;

  flat->import_start = 0;
  flat_import_count = 0;
  
  flat_reloc = (reloc_record_t*)(flat_buf+flatmainsize);  
  flat_reloc_cur = flat_reloc;

  flat_import_cur = flat_import_buf;

  // _div0_arm hack
  add_div0_arm();

  flag_unsafe_sym = 0;

  // Do relocations
  ret = relocate_section( &text);
  if(ret != ELFFLT_OK)
      return ret;  
  ret = relocate_section( &rodata);
  if(ret != ELFFLT_OK)
      return ret;
  ret = relocate_section( &data);
  if(ret != ELFFLT_OK)
      return ret;

  if ( flag_unsafe_sym )
      return ELFFLT_UNSAFE_SYMBOL;

  flat->import_start = flat->reloc_start+flat_reloc_count*sizeof(reloc_record_t);

  // Init offsets to the entry symbols
                  
  if ( FLAG_VERBOSE )
   	  printf(">>elf2flt: lookup entry symbols\n");

  flat->_module_info_offset = find_symbol_inflat("_module_info", &data );
  if ( flat->_module_info_offset <=0 ) {
    PRINTERR(stderr, "No or invalid section of _module_info. This symbol should be initialized as ModuleInfo structure.\n");
    return ELFFLT_NO_MODULEINFO;
  }

  struct ModuleInfo* _module_info = (struct ModuleInfo*) (flat_buf + flat->_module_info_offset);
  if ( _module_info->magicnum != MODULEINFO_V1_MAGICNUM ) 
  {
    PRINTERR(stderr, "Wrong _module_info->magicnum value. Please check correct filling of this structure\n");
    return ELFFLT_NO_MODULEINFO;
  }
  if ( _module_info->sizeof_struct != sizeof(struct ModuleInfo) ) 
  {
    PRINTERR(stderr, "Wrong _module_info->sizeof_struct value. Please check correct filling of this structure\n");
    return ELFFLT_NO_MODULEINFO;
  }

  // Group import relocations
  //  Input = array of offset/index pairs - one for each address to be relocated to a core CHDK symbol
  //  Output = list of entries of the form:
  //        Index, Offset1 | (N<<24), Offset2, ..., OffsetN
  //  where each offset is a reference to the same core CHDK symbol
  uint32_t *new_import_buf = malloc(flat_import_count*3*sizeof(uint32_t));
  uint32_t new_import_cnt = 0;
  int process = 1;
  while (process)
  {
      process = 0;
      for (i=0; i<flat_import_count; i++)
      {
          if (flat_import_buf[i].offs != 0)
          {
              process = 1;
              int cnt = 0;
              uint32_t idx = flat_import_buf[i].importidx;
              new_import_buf[new_import_cnt++] = idx;
              int pcnt = new_import_cnt;
              int j;
              for (j=0; j<flat_import_count; j++)
              {
                  if (flat_import_buf[j].importidx == idx)
                  {
                      new_import_buf[new_import_cnt++] = flat_import_buf[j].offs;
                      flat_import_buf[j].offs = 0;
                      cnt++;
                  }
              }
              new_import_buf[pcnt] = (cnt << 24) | new_import_buf[pcnt];
          }
      }
  }

  flat->file_size = flat->import_start+new_import_cnt*sizeof(uint32_t);

  if ( FLAG_DUMP_FLT_HEADERS ) {
	printf("\nFLT Headers:\n");
	printf("->entry        0x%x (size %d)\n", flat->entry, flat->data_start - flat->entry );
	printf("->data_start   0x%x (size %d)\n", flat->data_start,  flat->bss_start - flat->data_start );
	printf("->bss_start    0x%x (size %d)\n", flat->bss_start,   flat->reloc_start - flat->bss_start );
	printf("->reloc_start  0x%x (size %d)\n", flat->reloc_start, flat_reloc_count*sizeof(reloc_record_t) );
	printf("->import_start 0x%x (size %d %d)\n", flat->import_start, flat->file_size-flat->import_start, flat_import_count*sizeof(import_record_t) );
    printf("\n");

	printf("\nModule info:\n");
	printf("->Module Name: %s\n", get_flat_string(_module_info->moduleName) );
	printf("->Module Ver: %d.%d\n", _module_info->module_version.major, _module_info->module_version.minor );

	char* branches_str[] = {"any branch","CHDK", "CHDK_DE", "CHDK_SDM", "PRIVATEBUILD"};
	int branch = (_module_info->chdk_required_branch>REQUIRE_CHDK_PRIVATEBUILD) ? 
						REQUIRE_CHDK_PRIVATEBUILD : _module_info->chdk_required_branch;
	printf("->Require: %s-build%d. ", branches_str[branch], _module_info->chdk_required_ver );
	if ( _module_info->chdk_required_platfid == 0 )
	  	printf("Any platform.\n");
	else
	  	printf(" Platform #%d only.\n", _module_info->chdk_required_platfid );
	printf("->Description: %s\n", get_flat_string(_module_info->description) );
	print_offs("->lib                 = ", (int)_module_info->lib,"\n");
	//print_offs("->_module_loader()    = ", (int)_module_info->loader,"\n");
	//print_offs("->_module_unloader()  = ", (int)_module_info->unloader,"\n");
	//print_offs("->_module_can_unload()= ", (int)_module_info->can_unload,"\n");
	//print_offs("->_module_exit_alt()  = ", (int)_module_info->exit_alt,"\n");
  }

  if ( FLAG_DUMP_FLAT ) {
    dump_section( "FLT_header", (unsigned char*)flat_buf, sizeof(struct flat_hdr) );
    dump_section( "FLT_text", (unsigned char*)flat_buf+flat->entry, flat->data_start-flat->entry );
    dump_section( "FLT_data", (unsigned char*)flat_buf+flat->data_start, flat->bss_start-flat->data_start);
    dump_section( "FLT_bss",  (unsigned char*)flat_buf+flat->bss_start, flat->reloc_start-flat->bss_start );

    printf("\nDump relocations 0x%x (size=%d):\n",flat->reloc_start,flat_reloc_count*sizeof(reloc_record_t));
    for( i = 0; i< flat_reloc_count; i++)
    {
        print_offs("Offs: ",*(int*)(flat_buf+flat->reloc_start+i*sizeof(reloc_record_t)), "\n");
    }

    printf("\nDump imports 0x%x (size=%d):\n",flat->import_start,new_import_cnt*sizeof(uint32_t));
    for (i = 0; i< new_import_cnt;)
    {
        uint32_t idx = new_import_buf[i++];
        int cnt = new_import_buf[i] >> 24;
        int j;
        for (j=0; j<cnt; j++)
        {
            uint32_t offs = new_import_buf[i++] & 0x00FFFFFF;
            print_offs((j==0)?"Offs: ":"      ",offs,"");
		    int addend = *(uint32_t*)(flat_buf+offs);
		    printf(" = sym_%08x[%s]+0x%x\n",idx,get_import_symbol(idx),addend);
        }
    }
  }

  int filesize = flat->file_size;

  printf("\n\nOutput file %s (size=%d bytes)\n",fltfile,filesize);

  int output_fd = open(fltfile,O_WRONLY|O_CREAT|O_TRUNC|O_BINARY,0777);
  i = write(output_fd, flat_buf, flat->import_start);
  i = write(output_fd, new_import_buf, new_import_cnt*sizeof(uint32_t));
  close(output_fd);

  return ELFFLT_OK;
}
Beispiel #18
0
static inline uint32_t row_size(int width, uint8_t bpp)
{
    return align4(width * nbbytes(bpp));
}
Beispiel #19
0
       data->page_pos_x = 0;
       data->page_pos_y = 0;
       data->page_line_height = 0;
    }

    return page;
}


static unsigned char *alloc_glyph_region(ALLEGRO_TTF_FONT_DATA *data,
   int ft_index, int w, int h, bool new, ALLEGRO_TTF_GLYPH_DATA *glyph,
   bool lock_more)
{
   ALLEGRO_BITMAP *page;
   bool relock;
   int w4 = align4(w);
   int h4 = align4(h);
   int glyph_size = w4 > h4 ? w4 : h4;

   if (_al_vector_is_empty(&data->page_bitmaps) || new) {
      page = push_new_page(data, glyph_size);
      relock = true;
      if (!page)
         return NULL;
   }
   else {
      ALLEGRO_BITMAP **back = _al_vector_ref_back(&data->page_bitmaps);
      page = *back;
      relock = !data->page_lr;
   }
Beispiel #20
0
		// 4 byte padded strings !
		int getString( char * data, char **output )
		{
			size_t l = strlen(data)+1;
			*output = data;
			return align4(l);
		}