VError VPictureData_MacPicture::SaveToFile(VFile& inFile)const
{
	VError result = VE_OK;
	if (fDataProvider && fDataProvider->GetDataSize())
	{
		VPtr p = fDataProvider->BeginDirectAccess();
		if (p)
		{
			result = inFile.Create();
			if (result == VE_OK)
			{
				VFileDesc* inFileDesc;
				result = inFile.Open(FA_READ_WRITE, &inFileDesc);
				if (result == VE_OK)
				{
					char buff[0x200];
					memset(buff, 0, 0x200);
					result = inFileDesc->PutData(buff, 0x200, 0);
					if (result == VE_OK)
					{
						result = inFileDesc->PutData(p, fDataProvider->GetDataSize(), 0x200);
					}
					delete inFileDesc;
				}
			}
			fDataProvider->EndDirectAccess();
		}
		else
			fDataProvider->ThrowLastError();

	}
	else
	{
		VBlobWithPtr blob;
		VSize outsize;
		result = Save(&blob, 0, outsize);
		if (result == VE_OK)
		{
			result = inFile.Create();
			if (result == VE_OK)
			{
				VFileDesc* inFileDesc;
				result = inFile.Open(FA_READ_WRITE, &inFileDesc);
				if (result == VE_OK)
				{
					char buff[0x200];
					memset(buff, 0, 0x200);
					result = inFileDesc->PutData(buff, 0x200, 0);
					if (result == VE_OK)
					{
						result = inFileDesc->PutData(blob.GetDataPtr(), blob.GetSize(), 0x200);
					}
					delete inFileDesc;
				}
			}
		}
	}
	return result;
}
VError VZipComponent::ExpandBlob(VBlob *inCompressedBlob , VBlob *outExpandedBlob)
{
	if(!testAssert(inCompressedBlob != NULL))
		return VE_INVALID_PARAMETER;
	if(!testAssert(outExpandedBlob != NULL))
		return VE_INVALID_PARAMETER;
	
	VError errorToReturn = VE_OK;
	
	
	VBlobStream* expandedBlobStream = new VBlobStream();	
	VError openWritingExpandedBlobStream = expandedBlobStream -> OpenWriting();			
	if (openWritingExpandedBlobStream != VE_OK)
		errorToReturn = vThrowError(VE_ZIP_CANNOT_ACCESS_BLOB_CONTENT);
	
	
	if (errorToReturn == VE_OK){
		
		VBlobWithPtr* compressedBlobWithPtr = new VBlobWithPtr(*inCompressedBlob);
		
		if (errorToReturn == VE_OK){ 
			
			errorToReturn = ExpandMemoryBlock(compressedBlobWithPtr->GetDataPtr(), inCompressedBlob->GetSize(), expandedBlobStream);
			
			if (errorToReturn == VE_ZIP_NON_COMPRESSED_INPUT_DATA){
				errorToReturn = vThrowError(VE_ZIP_NON_COMPRESSED_INPUT_BLOB);	
			}
			
			if (errorToReturn == VE_OK){
				
				// Once the decompression succeded, we have to put the content of expandedBlobStream in outExpandedBlob. 
				//To do so, we have to pass via a temporary buffer to transfer these data (since the class VBlob does not inherit IStreamable). 
				errorToReturn = expandedBlobStream -> CloseWriting(true);
				
				if (errorToReturn == VE_OK){
					
					errorToReturn = expandedBlobStream -> OpenReading();
					
					sLONG8 expandedBlobStreamSize = expandedBlobStream -> GetSize();
					Bytef * expandedBuffer = (Bytef *) malloc(expandedBlobStreamSize  * sizeof(Bytef));	
					if (expandedBuffer == NULL){
						errorToReturn = vThrowError(VE_MEMORY_FULL);
					}	
					
					if (errorToReturn == VE_OK){
						// if everything is ok, the data of expandedBlobStream are copyied in the temporary buffer
						errorToReturn = expandedBlobStream -> GetData(expandedBuffer, expandedBlobStreamSize);
						expandedBlobStream -> CloseReading();
						
						
						if (errorToReturn == VE_OK){
							// if everything is still ok, the data of the temporary buffer are copyied in outExpandedBlob
							errorToReturn = outExpandedBlob -> PutData(expandedBuffer, expandedBlobStreamSize);
						}
					}	
					
					if (expandedBuffer != NULL)
						free(expandedBuffer); 
				}				
			}
		}
		
		// if something wrong occured with streams either in decompression (streams cannot be read, opened, closed, etc.) or in transfering data to outExpandedBlob
		// note: if it is a pure decompression error, this error is thrown.
		if (errorToReturn != VE_OK && errorToReturn != VE_ZIP_DECOMPRESSION_FAILED && errorToReturn != VE_ZIP_NON_COMPRESSED_INPUT_BLOB){
			errorToReturn = vThrowError(VE_ZIP_CANNOT_ACCESS_BLOB_CONTENT);
		}
	}
	delete expandedBlobStream;
	
	return errorToReturn;	
}  
VError VPictureData_GDIPlus::Save(VBlob* inData,VIndex inOffset,VSize& outSize,_VPictureAccumulator* /*inRecorder*/)const
{
	VError result=VE_UNKNOWN_ERROR;
	if(fDataProvider)
	{
		return inherited::Save(inData,inOffset,outSize);
	}
	else
	{
		if(fBitmap)
		{
			VBlobWithPtr blob;
				
			bool savedone=false;
			const VPictureCodec* deco=RetainDecoder();
			if(deco)
			{
				if(!deco->IsEncoder())
				{
					ReleaseRefCountable(&deco);
				}
			}
			if(!deco)
			{
				VPictureCodecFactoryRef fact;
				deco=fact->RetainDecoderByIdentifier(".png");
			}
			if(deco)
			{
					
				result = deco->Encode(this,NULL,blob); 
					
				if(result==VE_OK)
				{
					outSize=blob.GetSize();
					result=inData->PutData(blob.GetDataPtr(),outSize,inOffset);
				}
			}
		}

		/*
		if(fBitmap)
		{
			DWORD err;
			IStream* stream=NULL; 
			err= ::CreateStreamOnHGlobal(NULL,true,&stream);
			if(err == S_OK)
			{
				VPictureCodecFactoryRef fact;
				const xGDIPlusDecoderList& encoderlist=fact->xGetGDIPlus_Decoder();
				
				Gdiplus::Status stat = Gdiplus::GenericError;

				CLSID encoder;
				
				
				if(encoderlist.FindClassID(*fBitmap,encoder))
				{
					stat = fBitmap->Save(stream,&encoder,NULL);
				
					HGLOBAL glob;
					GetHGlobalFromStream(stream,&glob);
					char* c=(char*)GlobalLock(glob);
					outSize=GlobalSize(glob);
					result = inData->PutData(c,outSize,inOffset);
					GlobalUnlock(glob);
					stream->Release();
				}
				else
				{
					assert(false);
				}
			}
		}
		*/
	}
	return result;
}
VError VZipComponent::CompressBlob( VBlob *inBlobToCompress , const EZipCompressionLevel inCompressionLevel , VBlob *outCompressedBlob )
{
	if(!testAssert(inBlobToCompress != NULL))
		return VE_INVALID_PARAMETER;
	if(!testAssert(outCompressedBlob != NULL))
		return VE_INVALID_PARAMETER;
	
	VError errorToReturn = VE_OK;
	
	
	VBlobStream* compressedBlobStream = new VBlobStream();
	
	errorToReturn = compressedBlobStream -> OpenWriting();	
	if (errorToReturn != VE_OK)
		errorToReturn = vThrowError(VE_ZIP_CANNOT_ACCESS_BLOB_CONTENT);

	
	if (errorToReturn == VE_OK){ 
	
		VBlobWithPtr* blobWithPtrToCompress = new VBlobWithPtr(*inBlobToCompress);
		
		if (errorToReturn == VE_OK){
			
			errorToReturn = CompressMemoryBlock(blobWithPtrToCompress->GetDataPtr(), inBlobToCompress->GetSize(), inCompressionLevel, compressedBlobStream);
			
			if (errorToReturn == VE_OK){
				
				// Once the compression succedeed, we have to put the content of compressedBlobStream in outCompressedBlob. 
				//To do so, we have to pass via a temporary buffer to transfer these data (since the class VBlob does not inherit IStreamable). 
				errorToReturn = compressedBlobStream -> CloseWriting(true);
				
				if (errorToReturn == VE_OK){
										
					errorToReturn = compressedBlobStream -> OpenReading();
					
					if (errorToReturn == VE_OK){
						
						sLONG8 compressedBlobStreamSize = compressedBlobStream -> GetSize();
						Bytef * compressedBuffer = (Bytef *) malloc(compressedBlobStreamSize  * sizeof(Bytef));	
						if (compressedBuffer == NULL){
							errorToReturn = vThrowError(VE_MEMORY_FULL);
						}	
						
						if (errorToReturn == VE_OK){
							
							// if everything is ok, the data of compressedBlobStream are copyied in the temporary buffer
							errorToReturn = compressedBlobStream -> GetData(compressedBuffer, compressedBlobStreamSize);
							compressedBlobStream -> CloseReading();
							
							if (errorToReturn == VE_OK){
								// if everything is still ok, the data of the temporary buffer are copyied in outCompressedBlob
								errorToReturn = outCompressedBlob -> PutData(compressedBuffer, compressedBlobStreamSize);
								
							}
						}	
						
						if (compressedBuffer != NULL)
							free(compressedBuffer);	
					} 
				}
				
				// if something wrong occured with streams either in compression (streams cannot be read, opened, closed, etc.) or in transfering data to outCompressedBlob
				// note: if it is a pure compression error, this error is thrown.
				if (errorToReturn != VE_OK && errorToReturn != VE_ZIP_COMPRESSION_FAILED){
					errorToReturn = vThrowError(VE_ZIP_CANNOT_ACCESS_BLOB_CONTENT);
				}
			}
		}
	
		delete blobWithPtrToCompress;
	}
	delete compressedBlobStream; 
	return errorToReturn; 
}