Exemple #1
0
Msg* OneToAllMsg::copy( Id origSrc, Id newSrc, Id newTgt,
			FuncId fid, unsigned int b, unsigned int n ) const
{
	const Element* orig = origSrc();
	if ( n <= 1 ) {
		OneToAllMsg* ret = 0;
		if ( orig == e1() ) {
			ret = new OneToAllMsg( Msg::nextMsgId(), Eref( newSrc(), i1_ ), newTgt() );
			ret->e1()->addMsgAndFunc( ret->mid(), fid, b );
		} else if ( orig == e2() ) {
			ret = new OneToAllMsg( Msg::nextMsgId(), Eref( newTgt(), i1_ ), newSrc() );
			ret->e2()->addMsgAndFunc( ret->mid(), fid, b );
		} else {
			assert( 0 );
		}
		return ret;
	} else {
		// Here we need a SliceMsg which goes from one 2-d array to another.
		cout << "Error: OneToAllMsg::copy: SliceToSliceMsg not yet implemented\n";
		return 0;
	}
}
Exemple #2
0
    //---------------------------------------------------------------------
    FIBITMAP* FreeImageCodec::encode(MemoryDataStreamPtr& input, CodecDataPtr& pData) const
    {
        FIBITMAP* ret = 0;

        ImageData* pImgData = static_cast< ImageData * >( pData.getPointer() );
        PixelBox src(pImgData->width, pImgData->height, pImgData->depth, pImgData->format, input->getPtr());

        // The required format, which will adjust to the format
        // actually supported by FreeImage.
        PixelFormat requiredFormat = pImgData->format;

        // determine the settings
        FREE_IMAGE_TYPE imageType;
        PixelFormat determiningFormat = pImgData->format;

        switch(determiningFormat)
        {
        case PF_R5G6B5:
        case PF_B5G6R5:
        case PF_R8G8B8:
        case PF_B8G8R8:
        case PF_A8R8G8B8:
        case PF_X8R8G8B8:
        case PF_A8B8G8R8:
        case PF_X8B8G8R8:
        case PF_B8G8R8A8:
        case PF_R8G8B8A8:
        case PF_A4L4:
        case PF_BYTE_LA:
        case PF_R3G3B2:
        case PF_A4R4G4B4:
        case PF_A1R5G5B5:
        case PF_A2R10G10B10:
        case PF_A2B10G10R10:
            // I'd like to be able to use r/g/b masks to get FreeImage to load the data
            // in it's existing format, but that doesn't work, FreeImage needs to have
            // data in RGB[A] (big endian) and BGR[A] (little endian), always.
            if (PixelUtil::hasAlpha(determiningFormat))
            {
#if FREEIMAGE_COLORORDER == FREEIMAGE_COLORORDER_RGB
                requiredFormat = PF_BYTE_RGBA;
#else
                requiredFormat = PF_BYTE_BGRA;
#endif
            }
            else
            {
#if FREEIMAGE_COLORORDER == FREEIMAGE_COLORORDER_RGB
                requiredFormat = PF_BYTE_RGB;
#else
                requiredFormat = PF_BYTE_BGR;
#endif
            }
            // fall through
        case PF_L8:
        case PF_A8:
            imageType = FIT_BITMAP;
            break;

        case PF_L16:
            imageType = FIT_UINT16;
            break;

        case PF_SHORT_GR:
            requiredFormat = PF_SHORT_RGB;
            // fall through
        case PF_SHORT_RGB:
            imageType = FIT_RGB16;
            break;

        case PF_SHORT_RGBA:
            imageType = FIT_RGBA16;
            break;

        case PF_FLOAT16_R:
            requiredFormat = PF_FLOAT32_R;
            // fall through
        case PF_FLOAT32_R:
            imageType = FIT_FLOAT;
            break;

        case PF_FLOAT16_GR:
        case PF_FLOAT16_RGB:
        case PF_FLOAT32_GR:
            requiredFormat = PF_FLOAT32_RGB;
            // fall through
        case PF_FLOAT32_RGB:
            imageType = FIT_RGBF;
            break;

        case PF_FLOAT16_RGBA:
            requiredFormat = PF_FLOAT32_RGBA;
            // fall through
        case PF_FLOAT32_RGBA:
            imageType = FIT_RGBAF;
            break;

        default:
            OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, "Invalid image format", "FreeImageCodec::encode");
        };

        // Check support for this image type & bit depth
        if (!FreeImage_FIFSupportsExportType((FREE_IMAGE_FORMAT)mFreeImageType, imageType) ||
            !FreeImage_FIFSupportsExportBPP((FREE_IMAGE_FORMAT)mFreeImageType, (int)PixelUtil::getNumElemBits(requiredFormat)))
        {
            // Ok, need to allocate a fallback
            // Only deal with RGBA -> RGB for now
            switch (requiredFormat)
            {
            case PF_BYTE_RGBA:
                requiredFormat = PF_BYTE_RGB;
                break;
            case PF_BYTE_BGRA:
                requiredFormat = PF_BYTE_BGR;
                break;
            default:
                break;
            };

        }

        bool conversionRequired = false;

        unsigned char* srcData = input->getPtr();

        // Check BPP
        unsigned bpp = static_cast<unsigned>(PixelUtil::getNumElemBits(requiredFormat));
        if (!FreeImage_FIFSupportsExportBPP((FREE_IMAGE_FORMAT)mFreeImageType, (int)bpp))
        {
            if (bpp == 32 && PixelUtil::hasAlpha(pImgData->format) && FreeImage_FIFSupportsExportBPP((FREE_IMAGE_FORMAT)mFreeImageType, 24))
            {
                // drop to 24 bit (lose alpha)
#if FREEIMAGE_COLORORDER == FREEIMAGE_COLORORDER_RGB
                requiredFormat = PF_BYTE_RGB;
#else
                requiredFormat = PF_BYTE_BGR;
#endif
                bpp = 24;
            }
            else if (bpp == 128 && PixelUtil::hasAlpha(pImgData->format) && FreeImage_FIFSupportsExportBPP((FREE_IMAGE_FORMAT)mFreeImageType, 96))
            {
                // drop to 96-bit floating point
                requiredFormat = PF_FLOAT32_RGB;
            }
        }

        PixelBox convBox(pImgData->width, pImgData->height, 1, requiredFormat);
        if (requiredFormat != pImgData->format)
        {
            conversionRequired = true;
            // Allocate memory
            convBox.data = OGRE_ALLOC_T(uchar, convBox.getConsecutiveSize(), MEMCATEGORY_GENERAL);
            // perform conversion and reassign source
            PixelBox newSrc(pImgData->width, pImgData->height, 1, pImgData->format, input->getPtr());
            PixelUtil::bulkPixelConversion(newSrc, convBox);
            srcData = static_cast<unsigned char*>(convBox.data);
        }


        ret = FreeImage_AllocateT(
            imageType,
            static_cast<int>(pImgData->width),
            static_cast<int>(pImgData->height),
            bpp);

        if (!ret)
        {
            if (conversionRequired)
                OGRE_FREE(convBox.data, MEMCATEGORY_GENERAL);

            OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS,
                "FreeImage_AllocateT failed - possibly out of memory. ",
                __FUNCTION__);
        }

        if (requiredFormat == PF_L8 || requiredFormat == PF_A8)
        {
            // Must explicitly tell FreeImage that this is greyscale by setting
            // a "grey" palette (otherwise it will save as a normal RGB
            // palettized image).
            FIBITMAP *tmp = FreeImage_ConvertToGreyscale(ret);
            FreeImage_Unload(ret);
            ret = tmp;
        }

        size_t dstPitch = FreeImage_GetPitch(ret);
        size_t srcPitch = pImgData->width * PixelUtil::getNumElemBytes(requiredFormat);


        // Copy data, invert scanlines and respect FreeImage pitch
        uchar* pSrc;
        uchar* pDst = FreeImage_GetBits(ret);
        for (size_t y = 0; y < pImgData->height; ++y)
        {
            pSrc = srcData + (pImgData->height - y - 1) * srcPitch;
            memcpy(pDst, pSrc, srcPitch);
            pDst += dstPitch;
        }

        if (conversionRequired)
        {
            // delete temporary conversion area
            OGRE_FREE(convBox.data, MEMCATEGORY_GENERAL);
        }

        return ret;
    }