Beispiel #1
0
char* BitmapHandler::loadBmpURL(const std::string &name, int &width, int &height, int mode, bool useCache)
{
   	char *data=NULL;

	AmigoRest restClient(amigoCoreAgent.c_str());
	restClient.enableCacheWrite(useCache);
	RestClient::response response = restClient.get(name);
	if (!response.isBad())
	{
		data = decompressImage((char*)response.body.c_str(), response.body.size(), width, height, mode);
	} else
	{
		if(useCache)
		{
			restClient.enableCacheRead(true);
			response = restClient.get(name);
			if (!response.isBad())
			{
				data = decompressImage((char*)response.body.c_str(), response.body.size(), width, height, mode);
				return data;
			}
		}
		AMIGO_LOG_I(TAG, "::loadBmpURL() FILED to load '%s'\n", name.c_str());
	}
	return data;
}
Beispiel #2
0
char* BitmapHandler::loadBmpFile(const std::string &fname, int &width, int &height, int mode)
{
   	char *data=NULL;

	int size;
	char *rawData = ImageUtils::loadFile (fname.c_str(), &size);
	if (rawData!=NULL)
	{
		data = decompressImage(rawData, size, width, height, mode);
	} else
	{
		AMIGO_LOG_W(TAG, "::loadBmpFile() FAILED to load '%s'\n", fname.c_str());
	}
	return data;
}
Beispiel #3
0
void AnimationResource::load(byte *source, int size) {
	Common::MemoryReadStream *sourceS = new Common::MemoryReadStream(source, size);

	sourceS->readUint32LE();
	sourceS->readUint32LE();
	sourceS->readUint16LE();

	_flags = sourceS->readUint16LE();
	_width = sourceS->readUint16LE();
	_height = sourceS->readUint16LE();
	sourceS->readUint32LE();
	uint16 frameCount = sourceS->readUint16LE();
	sourceS->readUint16LE();
	sourceS->readUint16LE();

	for (uint16 i = 0; i < frameCount; i++) {

		sourceS->seek(26 + i * 4);

		uint32 frameOffs = sourceS->readUint32LE();

		sourceS->seek(frameOffs);
		sourceS->readUint32LE();
		sourceS->readUint32LE();

		uint16 frameWidth = sourceS->readUint16LE();
		uint16 frameHeight = sourceS->readUint16LE();
		uint16 cmdOffs = sourceS->readUint16LE();
		sourceS->readUint16LE();
		uint16 pixelOffs = sourceS->readUint16LE();
		sourceS->readUint16LE();
		uint16 maskOffs = sourceS->readUint16LE();
		sourceS->readUint16LE();
		uint16 lineSize = sourceS->readUint16LE();

		Graphics::Surface *frame = new Graphics::Surface();
		frame->create(frameWidth, frameHeight, Graphics::PixelFormat::createFormatCLUT8());

		decompressImage(source + frameOffs, *frame, cmdOffs, pixelOffs, maskOffs, lineSize, 0, 0, 0, _flags & 1);

		_frames.push_back(frame);

	}

	delete sourceS;
}
Beispiel #4
0
void PictureResource::loadRaw(byte *source, int size) {
	// Loads a "raw" picture as used in RtZ, LGoP2, Manhole:N&E and Rodney's Funscreen

	Common::MemoryReadStream *sourceS = new Common::MemoryReadStream(source, size);

	_hasPalette = (sourceS->readByte() != 0);
	byte cmdFlags = sourceS->readByte();
	byte pixelFlags = sourceS->readByte();
	byte maskFlags = sourceS->readByte();
	uint16 cmdOffs = sourceS->readUint16LE();
	uint16 pixelOffs = sourceS->readUint16LE();
	uint16 maskOffs = sourceS->readUint16LE();
	uint16 lineSize = sourceS->readUint16LE();
	/*uint16 u = */sourceS->readUint16LE();
	uint16 width = sourceS->readUint16LE();
	uint16 height = sourceS->readUint16LE();

	if (cmdFlags || pixelFlags || maskFlags) {
		warning("PictureResource::loadRaw() Graphic has flags set (%d, %d, %d)", cmdFlags, pixelFlags, maskFlags);
	}

	_paletteColorCount = (cmdOffs - 18) / 3; // 18 = sizeof header

	debug(2, "width = %d; height = %d\n", width, height);

	if (_hasPalette) {
		_picturePalette = new byte[_paletteColorCount * 3];
		sourceS->read(_picturePalette, _paletteColorCount * 3);
	}

	_picture = new Graphics::Surface();
	_picture->create(width, height, Graphics::PixelFormat::createFormatCLUT8());

	decompressImage(source, *_picture, cmdOffs, pixelOffs, maskOffs, lineSize, cmdFlags, pixelFlags, maskFlags);

	delete sourceS;

}
Beispiel #5
0
void PictureResource::loadChunked(byte *source, int size) {
	// Loads a "chunked" picture as used in Manhole EGA

	Common::MemoryReadStream *sourceS = new Common::MemoryReadStream(source, size);

	byte cmdFlags = 0, pixelFlags = 0, maskFlags = 0;
	uint16 cmdOffs = 0, pixelOffs = 0, maskOffs = 0;
	uint16 lineSize = 0, width = 0, height = 0;

	sourceS->skip(36); // skip the "Flex" header

	_hasPalette = false;

	while (!sourceS->eos()) {

		uint32 chunkType = sourceS->readUint32BE();
		uint32 chunkSize = sourceS->readUint32BE();

		if (sourceS->eos())
			break;

		debug(0, "chunkType = %08X; chunkSize = %d", chunkType, chunkSize);

		if (chunkType == MKTAG('R','e','c','t')) {
			debug(0, "Rect");
			sourceS->skip(4);
			height = sourceS->readUint16BE();
			width = sourceS->readUint16BE();
			debug(0, "width = %d; height = %d", width, height);
		} else if (chunkType == MKTAG('f','M','a','p')) {
			debug(0, "fMap");
			lineSize = sourceS->readUint16BE();
			sourceS->skip(11);
			cmdFlags = sourceS->readByte();
			cmdOffs = sourceS->pos();
			sourceS->skip(chunkSize - 14);
			debug(0, "lineSize = %d; cmdFlags = %d; cmdOffs = %04X", lineSize, cmdFlags, cmdOffs);
		} else if (chunkType == MKTAG('f','L','C','o')) {
			debug(0, "fLCo");
			sourceS->skip(9);
			pixelFlags = sourceS->readByte();
			pixelOffs = sourceS->pos();
			sourceS->skip(chunkSize - 10);
			debug(0, "pixelFlags = %d; pixelOffs = %04X", pixelFlags, pixelOffs);
		} else if (chunkType == MKTAG('f','P','i','x')) {
			debug(0, "fPix");
			sourceS->skip(9);
			maskFlags = sourceS->readByte();
			maskOffs = sourceS->pos();
			sourceS->skip(chunkSize - 10);
			debug(0, "maskFlags = %d; maskOffs = %04X", maskFlags, maskOffs);
		} else if (chunkType == MKTAG('f','G','C','o')) {
			debug(0, "fGCo");
			_hasPalette = true;
			_paletteColorCount = chunkSize / 3;
			_picturePalette = new byte[_paletteColorCount * 3];
			sourceS->read(_picturePalette, _paletteColorCount * 3);
		} else {
			error("PictureResource::loadChunked() Invalid chunk %08X at %08X", chunkType, sourceS->pos());
		}

	}

	if (!cmdOffs || !pixelOffs /*|| !maskOffs*/ || !lineSize || !width || !height) {
		error("PictureResource::loadChunked() Error parsing the picture data, one or more chunks/parameters are missing");
	}

	_picture = new Graphics::Surface();
	_picture->create(width, height, Graphics::PixelFormat::createFormatCLUT8());

	decompressImage(source, *_picture, cmdOffs, pixelOffs, maskOffs, lineSize, cmdFlags, pixelFlags, maskFlags);

	delete sourceS;

}
/**
    \fn DecodePictureUpToIntra
    \brief Decode pictures from frameno, which must be an intra and on
            until the decoded frameno is popped by the decoder

    @param frame, framenumber relative to video ref (i.e. from its beginning)
    @param ref  , video we are dealing with
    returns true on success
            fail on error

*/
bool ADM_Composer::DecodePictureUpToIntra(uint32_t ref,uint32_t frame)
{
  uint8_t ret = 0;
  EditorCache   *cache;
  ADMImage	*result;
  uint32_t  flags,flagsNext=0;
  ADMCompressedImage img;

    // PlaceHolder...
    img.data=compBuffer;
    img.cleanup(frame);

    ADM_info(" DecodeUpToInta %u ref:%u\n",frame,ref);
	_VIDEOS *vid=_segments.getRefVideo(ref);
    vidHeader *demuxer=vid->_aviheader;
	cache=vid->_videoCache;
	ADM_assert(cache);
    // Make sure frame is an intra, or the next field is intra
    demuxer->getFlags(frame,&flags);
    demuxer->getFlags(frame+1,&flagsNext);
    
    // in case of field encoding, only the 2nd field might be
    // flagged as intra
    uint32_t twoFlags=flags | flagsNext;
    ADM_assert(twoFlags&AVI_KEY_FRAME);

    bool found=false;
    vid->lastSentFrame=frame;
    uint32_t nbFrames=vid->_nb_video_frames;
    aprintf("[EditorRender] DecodeUpToIntra flushing cache & codec\n");
    cache->flush();
    vid->decoder->flush();
    // The PTS associated with our frame is the one we are looking for
    uint64_t wantedPts=demuxer->estimatePts(frame);
    uint32_t tries=15+7; // Max Ref frames for H264 + MaxRecovery , let's say 7 is ok for recovery
    bool syncFound=false;
    while(found==false && tries--)
    {
        // Last frame ? if so repeat
        if(vid->lastSentFrame>=nbFrames-1) vid->lastSentFrame=nbFrames-1;
        // Fetch frame
         aprintf("[Editor] Decoding  frame %u\n",vid->lastSentFrame);
         
         if (!demuxer->getFrame (vid->lastSentFrame,&img))
         {
                ADM_warning(" getFrame failed for frame %"PRIu32"\n",vid->lastSentFrame);
                //cache->flush();
                return false;
         }
         // Now uncompress it...
         result=cache->getFreeImage();
         if(frame==0) // out first frame, make sure it starts black to avoid the all green effect
         {
            result->blacken();
         }
         if(!result)
         {
                ADM_warning(" Cache full for frame %"PRIu32"\n",vid->lastSentFrame);
                return false;
          }
           aprintf("[Decoder] Demuxer Frame %"PRIu32" pts=%"PRIu64" ms, %"PRIu64" us\n",vid->lastSentFrame,img.demuxerPts/1000,
                                                                    img.demuxerPts);
          if(!decompressImage(result,&img,ref))
          {
             ADM_info(" decode error for frame %"PRIu32", not necessarily a problem\n",vid->lastSentFrame);
             //cache->dump();
             cache->invalidate(result);
             //cache->dump();
             vid->lastSentFrame++;
             continue;
          }else
            {
                
                uint64_t pts=result->Pts;
                aprintf("[Decoder] Decoder Frame %"PRIu32" pts=%"PRIu64" ms, %"PRIu64" us\n",vid->lastSentFrame,
                                                        result->Pts/1000,result->Pts);
                if(pts==ADM_COMPRESSED_NO_PTS) // No PTS available ?
                {
                   
                    if(false==syncFound)
                    {
                        aprintf("[DecodePictureUpToIntra] No time stamp yet, dropping picture\n");
                        cache->invalidate(result);
                    }else
                    {
                        // increment it using average fps
                        vid->lastDecodedPts+=vid->timeIncrementInUs;
                        result->Pts=vid->lastDecodedPts;
                    }
                }else
                {
                    if(false==syncFound)
                    {
                        aprintf("[DecodePictureUpToIntra] Sync found\n");
                        syncFound=true;
                    }
                    vid->lastDecodedPts=pts;
                }
                cache->validate(result);
            }

            // Found our image ?
          if(result->Pts==wantedPts)
                found=true;
          else
                vid->lastSentFrame++;
    }
    if(found==false)
    {
        ADM_warning(" Could not find decoded frame, wanted PTS :%"PRIu32" PTS=%"PRIu64" ms, %"PRIu64" us\n",frame,wantedPts/1000,wantedPts);
        cache->dump();
        return false;
    }
    vid->lastReadPts=wantedPts;
    currentFrame=frame;
    return true;
}
/**
    \fn DecodeNextPicture
    \brief Decode the next picture

    @param ref  , video we are dealing with
    returns true on success
            fail on error

*/
bool ADM_Composer::DecodeNextPicture(uint32_t ref)
{
uint8_t ret = 0;
  EditorCache   *cache;
  ADMImage	*result;
  uint32_t  flags;
  ADMCompressedImage img;
   _VIDEOS *vid=_segments.getRefVideo(ref);
    vidHeader *demuxer=vid->_aviheader;
	cache=vid->_videoCache;
    // PlaceHolder...
    img.data=compBuffer;
    img.cleanup(vid->lastSentFrame+1);

    ADM_assert(cache);
    vid->lastSentFrame++;

    uint32_t frame=vid->lastSentFrame;
    aprintf("[EditorRender] DecodeNext %u ref:%u\n",frame,ref);
    // Fetch frame
     aprintf("[Editor] Decoding frame %u\n",frame);
     if (!demuxer->getFrame (frame,&img))
     {
            ADM_warning("getFrame failed for frame %"PRIu32"\n",vid->lastSentFrame);
            return false;
     }

     // Now uncompress it...
     result=cache->getFreeImage();
     if(!result)
     {
            ADM_warning(" Cache full for frame %"PRIu32"\n",vid->lastSentFrame);
            return false;
      }
        aprintf("Demuxed frame %"PRIu32" with pts=%"PRId64" us, %"PRId64" ms\n",
            frame,
            img.demuxerPts,
            img.demuxerPts/1000);
    
      if(!decompressImage(result,&img,ref))
      {
         ADM_info("Decoding error for frame %"PRIu32", not necessarily a problem\n",vid->lastSentFrame);
         stats.nbNoImage++;
         cache->invalidate(result);
         return true; // Not an error in itself
      }
        aprintf("Got image with PTS=%s\n",ADM_us2plain(result->Pts));
     uint64_t pts=result->Pts;
     uint64_t old=vid->lastDecodedPts;
        if(pts==ADM_COMPRESSED_NO_PTS) // No PTS available ?
        {
                aprintf("[Editor] No PTS, guessing value\n");
                aprintf("Image Pts : %s\n",ADM_us2plain(img.demuxerPts));
                aprintf("Image Dts : %s\n",ADM_us2plain(img.demuxerDts));
                vid->lastDecodedPts+=vid->timeIncrementInUs;
                if(img.demuxerDts!=ADM_NO_PTS && vid->_aviheader->providePts()==false)
                {
                    if(img.demuxerDts>vid->lastDecodedPts)
                    {
                        aprintf("Dts > Guessed Pts, cranking pts\n");
                        vid->lastDecodedPts=img.demuxerDts;
                    }
                }
               
                result->Pts=vid->lastDecodedPts;
        }else
           {
                aprintf("[Editor] got PTS\n");
                vid->lastDecodedPts=pts;
            }
    aprintf(">>Decoded frame %"PRIu32" with pts=%"PRId64" us, %"PRId64" ms, ptsdelta=%"PRId64" ms \n",
        frame,
        vid->lastDecodedPts,
        vid->lastDecodedPts/1000,
        (vid->lastDecodedPts-old)/1000);

    if(old>vid->lastDecodedPts) 
    {
        stats.nbPtsgoingBack++;
        ADM_warning(">>>>> PTS going backward by %"PRId64" ms\n",(old-vid->lastDecodedPts)/1000);
        ADM_warning("Dropping frame!\n");
        cache->invalidate(result);
        return false;
    }else
    {
        cache->validate(result);
    }
    if(result->flags & AVI_KEY_FRAME) stats.nbIFrames++;
    else if(result->flags & AVI_B_FRAME) stats.nbBFrames++;
     else  stats.nbPFrames++;
    return true;
}