Exemplo n.º 1
0
BOOL FreeHandEPSFilter::PrepareToImport()
{
	if(!EPSFilter::PrepareToImport())
		return FALSE;

	// set some nice variables
	HadhToken = FALSE;
	DoingGradFill = FALSE;
	OldFill = 0;
	InColours = FALSE;
	InText = FALSE;
	ComplexPathMode = FALSE;
	pLastPathSeen = 0;
	
	// set the clipping flags
	ClipRegion.SetClippingFlags(2);

	// get an importedcolours object
	pNewColours = new ImportedColours(pColours, FALSE);
	if(pNewColours == 0 || !pNewColours->Init())
		return FALSE;

	// get a colour array
	ColourArray = (IndexedColour **)CCMalloc(FHEF_COLOURARRAY_INITIALSIZE * sizeof(IndexedColour *));
	if(ColourArray == 0)
	{
		delete pNewColours;
		pNewColours = 0;
		return FALSE;
	}
	ColourArrayEntries = 0;
	ColourArraySize = FHEF_COLOURARRAY_INITIALSIZE;

	return TRUE;
}
Exemplo n.º 2
0
BOOL TrapsList::ExpandArray(void)
{
	// Work out how many entries to allocate.
	// Each item is small, so we allocate a reasonably large number
	// Note that potential implementation of dashed lines could create a lot of 
	// TrapEdgeLists (one per dash), so we need lots of spare capacity to cope
	// with this situation. I've therefore erred on the generous side.
	const INT32 AllocSize = CurrentSize + 64;

	if (pTraps == NULL)
	{
		// We have no array yet, so allocate one
		pTraps = (TrapEdgeList **) CCMalloc(AllocSize * sizeof(TrapEdgeList *));
		if (pTraps == NULL)
			return(FALSE);
	}
	else
	{
		// We have an array - we must make it larger
		TrapEdgeList **pNewBuf = (TrapEdgeList **) CCRealloc(pTraps, AllocSize * sizeof(TrapEdgeList *));
		if (pNewBuf == NULL)
			return(FALSE);

		pTraps = pNewBuf;
	}

	// Success. Update the current size value
	CurrentSize = AllocSize;

	// Initialise the pointers to safe values
	for (UINT32 Index = Used; Index < CurrentSize; Index++)
		pTraps[Index] = NULL;

	return(TRUE);
}
Exemplo n.º 3
0
BOOL GuidesPropertiesTab::DeleteClicked()
{
	INT32* pIndexList = pPropertiesDlg->GetSelectedItems(_R(IDC_GUIDETAB_GUIDELINELIST));
	INT32 Count = GuidelineList.GetCount();

	INT32 i;

	BOOL ok = (pIndexList != NULL && Count > 0);
	NodeGuideline** pGuidelineList = NULL;

	if (ok)
	{
		pGuidelineList = (NodeGuideline**)CCMalloc(sizeof(NodeGuideline*)*(Count+1));

		ok = (pGuidelineList != NULL);

		if (ok)
		{
			for (i=0; (pIndexList[i] >= 0) && (i < Count);i++)
			{
				GuidelineListItem* pItem = (GuidelineListItem*)GuidelineList.FindItem(pIndexList[i]);
				if (pItem != NULL)
					pGuidelineList[i] = pItem->pGuideline;
				else
				{
					pGuidelineList[i] = NULL;
					ERROR3_PF(("List item at index [%d] is NULL",i));
				}
			}

			pGuidelineList[i] = NULL;
		}
	}
	else
		ok = FALSE;

	if (ok)
	{
		OpDescriptor* pOpDesc = OpDescriptor::FindOpDescriptor(OPTOKEN_GUIDELINE);
		ERROR3IF(pOpDesc == NULL,"FindOpDescriptor(OPTOKEN_GUIDELINE) failed");

		if (pOpDesc != NULL)
		{
			OpGuidelineParam GuidelineParam;

			GuidelineParam.Method 			= GUIDELINEOPMETHOD_DELETE;
			GuidelineParam.pGuidelineList 	= pGuidelineList;

			pOpDesc->Invoke(&GuidelineParam);
		}
	}

	if (pGuidelineList != NULL)
		CCFree(pGuidelineList);

	if (pIndexList != NULL)
		delete [] pIndexList;

	return ok;
}
Exemplo n.º 4
0
BOOL SGThumbs::InitThumbnails(SGLibType Type, SGThumbSize Size)
{	
//  Read in value for MaxThumbnails here
//	MaxThumbnails = 10;
//	GetApplication()->DeclareSection(TEXT("Libraries"), 6);
//	GetApplication()->DeclarePref(TEXT("Libraries"), TEXT("Thumbnails"), &MaxThumbnails, 1, 100);

	Entries = MaxThumbnails;

	Thumbnails = (struct TN*)CCMalloc(sizeof(struct TN) * Entries);
	if(Thumbnails != NULL)
	{
		INT32 i;
		ThumbnailsLibType = Type;
		ThumbnailsSize = Size;

		for(i=0; i<Entries; i++)
		{
			Thumbnails[i].ID = 0;
			Thumbnails[i].Usage = 0;
			Thumbnails[i].Valid = FALSE;
			Thumbnails[i].Size = ThumbnailsSize;
			Thumbnails[i].buffer = NULL;
		}
		ThumbnailsInitialised = TRUE;
		return TRUE;
	}
	else
	{
		ThumbnailsInitialised = TRUE;
		return FALSE;
	}
}
Exemplo n.º 5
0
BOOL RIFFFile::GetListContents(ADDR *Block, INT32 *Size)
{
	ERROR2IF(ObjType != RIFFOBJECTTYPE_LISTSTART, FALSE, "Tried an GetListContents on a non-list start RIFF object\n");

	// OK, first thing we need to do is to get the list's header... where is it?
	INT32 StartLocation = Location - sizeof(RIFFck) - sizeof(RIFFFile_List);

	// seek there
	if(File->seek(StartLocation).bad())
	{
		RIFFFILE_RETURNERR;
	}

	// OK, get the chunk header (not the list header which gives it's type
 	RIFFck ChunkHeader;

	if(File->read(&ChunkHeader, sizeof(ChunkHeader)).bad())
	{
 		RIFFFILE_RETURNERR;
	}

	// right then, we now know how much data we need to extract from the file...
	INT32 ContentsSize =	RIFFDATA_DWORD(ChunkHeader.ckSize) + sizeof(RIFFck);

	// now we need a block of data to get it into
	ADDR Contents = (ADDR)CCMalloc(ContentsSize);
	
	if(Contents == 0)
		return FALSE;

	// and getting it would be a cunning plan! seek to the beginning
	if(File->seek(StartLocation).bad())
	{
		RIFFFILE_RETURNERR;
	}

	// grab the data
	if(File->read(Contents, ContentsSize).bad())
	{
		RIFFFILE_RETURNERR;
	}
	
	// seek back to the location we were at the beginning
	if(File->seek(Location).bad())
	{
		RIFFFILE_RETURNERR;
	}

	// and set up the return values
	*Block = Contents;
	*Size = ContentsSize;
	
	return TRUE;
}
Exemplo n.º 6
0
BOOL BlendHelpers::ReallocTempBuffers(UINT32 Size)
{
	DeallocTempBuffers();

	// Allocate the arrays
	m_TempArraySize = Size;
	m_pTempCoords   = (DocCoord*)  CCMalloc(Size*sizeof(DocCoord));
	m_pTempVerbs    = (PathVerb*)  CCMalloc(Size*sizeof(PathVerb));
	m_pTempFlags    = (PathFlags*) CCMalloc(Size*sizeof(PathFlags));

	// If any of the arrays are not allocated, dealloc the alloced ones, and return FALSE
	if (m_pTempCoords == NULL || m_pTempVerbs == NULL || m_pTempFlags == NULL)
	{
		DeallocTempBuffers();
		return FALSE;
	}

	// It's all OK, so return TRUE
	return TRUE;
}
Exemplo n.º 7
0
BOOL RenderStack::GrowStack()
{
	INT32 FirstNewItem = 0;

	if (TheStack == NULL)
	{
		// Try to allocate initial memory block for the stack.
		TheStack = (AttributeRec *) CCMalloc(InitialStackSize * ITEM_SIZE);

		// Complain and return if it didn't work.
		if (TheStack == NULL)
			return FALSE;

		// Update stack limit to reflect new size
		StackLimit = InitialStackSize;

	}
	else
	{
//		if (IsUserName("Tim"))
//			TRACE( _T("Growing heap from %d to %d entries\n"), 
//				  StackLimit, StackLimit + StackGranularity);

		// Increase the stack allocation
		AttributeRec *NewStack = (AttributeRec *)
			CCRealloc(TheStack, (StackLimit + StackGranularity) * ITEM_SIZE);

		// Complain if no more memory
		if (NewStack == NULL)
			return FALSE;

		// Otherwise use this new block
		TheStack = NewStack;

		// Make sure only new items are initialised
		FirstNewItem = StackLimit;

		// Update stack limit to reflect new size
		StackLimit += StackGranularity;
	}

	// Initialise the stack elements
	for (UINT32 i = FirstNewItem; i < StackLimit; i++)
	{
		TheStack[i].pAttrValue = NULL;
		TheStack[i].ContextLevel = 0;
		TheStack[i].Temporary = FALSE;
	}

	// Return success
	return TRUE;
}
Exemplo n.º 8
0
LPVOID TunedMemory::LimitedCCMalloc(size_t Size)
{
	// Get some ram
	LPVOID Memory = CCMalloc(Size);

	// if we got it, make a note of its allocation
	if ((Memory!=NULL) && (!IsInfinite))
	{
		AvailableRAM -= Size;
	}

	// return what we got
	return Memory;
}
Exemplo n.º 9
0
UINT32* BlendHelpers::GetGBlendBuff(UINT32 MinSize)
{
	MinSize++;
	if (m_GBlendBuffSize >= MinSize) return m_pGBlendBuff;

	if (m_pGBlendBuff != NULL) CCFree(m_pGBlendBuff);

	m_pGBlendBuff = (UINT32*) CCMalloc(MinSize*sizeof(UINT32));

	if (m_pGBlendBuff != NULL)
		m_GBlendBuffSize = MinSize;
	else
		m_GBlendBuffSize = 0;

	return m_pGBlendBuff;
}
Exemplo n.º 10
0
BOOL RIFFFile::EnsureAquiredSizeIsAtLeast(INT32 Size)
{
	if(AquiredData == 0 || AquiredDataSize < Size)
	{
		if(AquiredData != 0) 
		{
			CCFree(AquiredData);
			AquiredData = 0;
		}

		if((AquiredData = (BYTE *)CCMalloc(Size)) == 0)
			RIFFFILE_RETURNERR;

		AquiredDataSize = Size;
	}

	return TRUE;
}
Exemplo n.º 11
0
BOOL TrapEdgeList::ExpandArray(void)
{
	// Work out how many entries to allocate. Note that I use a fairly large number
	// so that we don't have to reallocate the array very often. Each structure is
	// small, so the memory usage is fairly low, although it must be noted that
	// a dashed line could potentially generate quite a pile of these lists!
	INT32 AllocSize = CurrentSize + 512;
	if (pParentList != NULL && pParentList->GetRepeatLength() > 0)
	{
		// If it's a repeating stroke, then we must be far more careful about memory usage!
		// (i.e. if there are 1000 repeats along a stroke, each taking 15kB, we'll eat 15MB!)
		// We assume that repeats are small and hence will not need very many entries, and
		// then if (and only if) we find we have to realloc to make the array bigger, we jump
		// in bigger steps.
		if (CurrentSize == 0)
			AllocSize = CurrentSize + 4;
		else
			AllocSize = CurrentSize + 16;
	}

	if (pEdges == NULL)
	{
		// We have no array yet, so allocate one
		pEdges = (TrapEdge *) CCMalloc(AllocSize * sizeof(TrapEdge));
		if (pEdges == NULL)
			return(FALSE);
	}
	else
	{
		// We have an array - we must make it larger
		TrapEdge *pNewBuf = (TrapEdge *) CCRealloc(pEdges, AllocSize * sizeof(TrapEdge));
		if (pNewBuf == NULL)
			return(FALSE);

		pEdges = pNewBuf;
	}

	// Success. Update the current size value
	CurrentSize = AllocSize;
	return(TRUE);
}
Exemplo n.º 12
0
LPVOID MemoryBlock::Init( INT32 InitSize, BOOL bAutoZero, MemoryBlockType Type )
{
#if USE_STD_ALLOC

	m_RoundedSize = GetRoundedSize( InitSize );

	// now physically grab the starting size
	LPVOID				pNewPtr;
	if( bAutoZero )
	{
		pNewPtr = CCMalloc( m_RoundedSize );
		memset(pNewPtr, 0, m_RoundedSize);
	}
	else
	{
		pNewPtr = CCMalloc( m_RoundedSize );
	}
		
	if( pNewPtr == NULL )
	{
		TRACEUSER( "Andy", wxT("malloc() failed because %lx\n"), errno );
		return NULL;
	}

	TRACEUSER( "Andy", wxT("malloc OK at %p\n"), pNewPtr );
	m_pMemBlk = pNewPtr;
	return pNewPtr;

#elif USE_VM_BLOCKS

	// first time we are called get the page size
	if (PageSize==0L)
	{
		SYSTEM_INFO SysInfo;
		GetSystemInfo( &SysInfo );
		PageSize = SysInfo.dwPageSize;
	}

	// Note that the Virtual API always gives us zeroed memory whether we want it or not


	// calculate a suitable maximum size for the type of block
	INT32 LargestSize;

	switch (Type)
	{
		case MEMORYBLOCK_HANDLETABLE:
			LargestSize = 0x01000000;				// 16M of handles is enough
			break;
		case MEMORYBLOCK_RELOCHEAP:
			LargestSize = 0x10000000;				// 256M of reloc heap
			break;
		case MEMORYBLOCK_SCREENBUFFER:
			LargestSize = 0x01000000;				// 1024x768x32bits x4 for good measure
			break;
		default:
			ENSURE( FALSE, "Bad type in MemoryBlock::Init");
			return NULL;
	}

	// firstly reserve a gratuitously large chunk of address space

	MemBase = VirtualAlloc( NULL, LargestSize, MEM_RESERVE, PAGE_NOACCESS );
	if (MemBase==NULL)
	{
		TRACEUSER( "Andy", wxT("VirtualAlloc(reserve) failed because %lx\n"), GetLastError() );
		return NULL;
	}

	RoundedSize = GetRoundedSize( InitSize );

	// now physically grab the starting size
	LPVOID NewPtr = VirtualAlloc( MemBase, RoundedSize, MEM_COMMIT, PAGE_READWRITE );
	if (NewPtr==NULL)
	{
		TRACEUSER( "Andy", wxT("VirtualAlloc(commit) failed because %lx\n"), GetLastError() );
		VirtualFree(MemBase, 0L, MEM_RELEASE );
		MemBase = NULL;
		return NULL;
	}

	TRACEUSER( "Andy", wxT("VirtualAlloced OK at %lx from %lx\n"), NewPtr, MemBase );

	return NewPtr;
#else

	#ifndef WIN32
	if (InitSize > MAX_BLOCK)
		return NULL;
	#endif

	AutoZero = bAutoZero;											// remember flag in struct

	UINT32 Flags = GMEM_MOVEABLE;
	if (AutoZero)
		Flags |= GMEM_ZEROINIT;

	MemHandle = GlobalAlloc( Flags, InitSize );
TRACE( wxT("GlobalAlloc %u %lx returned %x\n"), Flags, InitSize, (INT32)MemHandle);
	if (MemHandle==NULL)
		return NULL;

	LPVOID Ptr = GlobalLock( MemHandle );
	if (Ptr == NULL)
	{
		GlobalFree( MemHandle );
		MemHandle = 0;
		return NULL;
	}

	return Ptr;
#endif
}
Exemplo n.º 13
0
void OpAlign::DoWithParam(OpDescriptor* pOp, OpParam* pAlignParam)
{
	// DMc alterations so that this works with compound nodes	
	SelRange   Selection(*(GetApplication()->FindSelection()));

	RangeControl rg = Selection.GetRangeControlFlags();
	rg.PromoteToParent = TRUE;
	Selection.Range::SetRangeControl(rg);

	DocRect		SelRect   = Selection.GetBoundingRect();
	DocRect		TargetRect;
	TargetRect.MakeEmpty();
	INT32        NumObjs   = Selection.Count();
	AlignParam* pAlign    =(AlignParam*)pAlignParam;

	BOOL moved=FALSE;					// set to TRUE if any object is moved
	BeginSlowJob(-1,FALSE);
	BOOL OK=DoStartTransOp(FALSE);

	// find parent spread of first object in selection
	Node*   pFirstNode=NULL;
	Spread* pSpread   =NULL;
	if (OK)
	{
		pFirstNode=Selection.FindFirst();
		if (pFirstNode!=NULL)
			pSpread=pFirstNode->FindParentSpread();
		OK=(pSpread!=NULL);
		if (!OK)
			ERROR2RAW("OpAlign::DoWithParam() - could not find parent spread");
	}

	// Find the size of the target rectangle
	if (pAlign->target==ToSelection)
		TargetRect=SelRect;
	else
	{
		Page* pPage=pSpread->FindFirstPageInSpread();
		while (pPage)
		{
			DocRect PageRect=pPage->GetPageRect();
			if (pAlign->target==ToSpread || SelRect.IsIntersectedWith(PageRect))
				TargetRect=TargetRect.Union(PageRect);
			pPage=pPage->FindNextPage();
		}
	}

	// allocate all dynamic memory required
	Node**	 pObj=NULL;
	ObjInfo* x   =NULL;
	ObjInfo* y   =NULL;
	INT32*    dx  =NULL;
	INT32*    dy  =NULL;
	if (OK)			ALLOC_WITH_FAIL(pObj,(Node**)  CCMalloc(NumObjs*sizeof(Node*)),  this);
	if (pObj!=NULL)	ALLOC_WITH_FAIL(x,   (ObjInfo*)CCMalloc(NumObjs*sizeof(ObjInfo)),this);
	if (   x!=NULL) ALLOC_WITH_FAIL(y,   (ObjInfo*)CCMalloc(NumObjs*sizeof(ObjInfo)),this);
	if (   y!=NULL) ALLOC_WITH_FAIL(dx,  (INT32*)   CCMalloc(NumObjs*sizeof(INT32)),   this);
	if (  dx!=NULL) ALLOC_WITH_FAIL(dy,  (INT32*)   CCMalloc(NumObjs*sizeof(INT32)),   this);
	OK=(dy!=NULL);

	// if memory claimed OK and target rect not empty proceed with op
	// (ie. do nothing if 'within page(s)' when no object on a page)
	DocRect EmptyRect;
	if (OK && TargetRect!=EmptyRect)
	{
		// create an array of pointers to objects (nodes) to be affected
		Node* pNode=Selection.FindFirst();
		INT32  i=0;
		while (pNode!=NULL)
		{
			if (pNode->IsBounded() && !((NodeRenderableBounded*)pNode)->GetBoundingRect(TRUE).IsEmpty())
				pObj[i++]=pNode;
			pNode=Selection.FindNext(pNode);
		}
		NumObjs=i;

		// cache x & y info in separate arrays so they can be sorted separately
		XLONG SumObjWidths =0;
		XLONG SumObjHeights=0;
		for (i=0; i<NumObjs; i++)
		{
			DocRect ObjRect=((NodeRenderableBounded*)pObj[i])->GetBoundingRect();
			x[i].i=i;
			x[i].lo=ObjRect.lo.x;
			x[i].hi=ObjRect.hi.x;
			SumObjWidths+=ObjRect.hi.x-ObjRect.lo.x;
			y[i].i=i;
			y[i].lo=ObjRect.lo.y;
			y[i].hi=ObjRect.hi.y;
			SumObjHeights+=ObjRect.hi.y-ObjRect.lo.y;
		}

		// for each object, calculate the x and y displacements independently
		AlignOneAxis(pAlign->h,NumObjs,SumObjWidths, TargetRect.lo.x,TargetRect.hi.x,x,dx);
		AlignOneAxis(pAlign->v,NumObjs,SumObjHeights,TargetRect.lo.y,TargetRect.hi.y,y,dy);

		// apply the x and y displacements simultaneously to each object
		for (i=0; i<NumObjs; i++)
			if (dx[i]!=0 || dy[i]!=0)
			{
				moved=TRUE;
				Trans2DMatrix* pMatrix=new Trans2DMatrix(dx[i],dy[i]);
				DoTransformNode((NodeRenderableInk*)pObj[i],pMatrix);
			}
	}

	// free up any memory which was allocated
	CCFree(dx);
	CCFree(dy);
	CCFree(x);
	CCFree(y);
	CCFree(pObj);

	if (moved)
	{
		Document::GetSelected()->ForceRedraw(pSpread, TargetRect);
		GetApplication()->UpdateSelection();
	}
	else
		FailAndExecute();
	End();
	EndSlowJob();
}
Exemplo n.º 14
0
void *camelot_png_malloc(png_structp png_ptr, png_size_t size)
{
	return (CCMalloc(size));
}
Exemplo n.º 15
0
BOOL OutputPNG::StartFile( LPBITMAPINFOHEADER lpHeader, LPLOGPALETTE Palette,
                           UINT32 OutputDepth, DWORD CompressionType,
                           UINT32 FinalHeight, INT32 ExportSize, UINT32 DitherType )
{
    TRACEUSER( "Jonathan", _T("PNG write: Start\n"));
    ERROR2IF( lpHeader==NULL , FALSE, "OutputPNG::StartFile NULL lpHeader");

    // Set up memory pointers to NULL
    if (DestBitmapInfo && DestBitmapBytes)
    {
        FreeDIB( DestBitmapInfo, DestBitmapBytes );
        DestBitmapInfo = NULL;
        DestBitmapBytes = NULL;
    }
//	DestBitmapInfo = NULL;
//	DestBitmapBytes = NULL;
    if (OutputPalette)
    {
        CCFree(OutputPalette);
        OutputPalette = NULL;
    }
//	OutputPalette = NULL;
    IsFirstStrip = TRUE;
    HeightWritten = 0;

    // remember input args
    BitmapInfo = *lpHeader;								// take a copy of user's header
    CurrentExportSize = ExportSize;						// size set up for the progress bar
    HeightWanted = FinalHeight;							// the actual height of the export required
    Dither = DitherType;

    // We will need to have the entire image present before writing out so that we can
    // cope with interlacing and transparency, so create that DIB
    // Set up the information header for the dib which we hold during export
    UINT32 LineWidth = DIBUtil::ScanlineSize( BitmapInfo.biWidth, OutputDepth );
    INT32 PalSize = 0;
    BOOL ok = SetUpInfoHeader(lpHeader, OutputDepth, CompressionType, LineWidth, FinalHeight, &PalSize);

    // Claim memory for the bitmap
    if (ok)
    {
        DestBitmapInfo = AllocDIB( BitmapInfo.biWidth, FinalHeight, OutputDepth, &DestBitmapBytes );
        ok = (DestBitmapInfo != NULL) && (DestBitmapBytes != NULL);
    }

    // Transfer across the required other bits of info
    if (ok)
    {
        DestBitmapInfo->bmiHeader.biXPelsPerMeter = BitmapInfo.biXPelsPerMeter;
        DestBitmapInfo->bmiHeader.biYPelsPerMeter = BitmapInfo.biYPelsPerMeter;
        DestBitmapInfo->bmiHeader.biClrUsed = PalSize;
    }

    // Point the place to put the next strip of data at the start ready for the first strip
    pNextStrip = DestBitmapBytes;

    // Take a copy of the palette
    if (ok && PalSize && Palette)
    {
        const size_t TotalPal = sizeof(LOGPALETTE) + ( sizeof(PALETTEENTRY) * PalSize );
        OutputPalette = (LPLOGPALETTE)CCMalloc( TotalPal );
        if (OutputPalette != NULL)
            memcpy( OutputPalette, Palette, TotalPal );
        else
            ok = FALSE;
    }

    // Clean up if an error happened
    if (!ok)
    {
        // Free up the DIB that we have just created
        FreeDIB( DestBitmapInfo, DestBitmapBytes );
        DestBitmapInfo = NULL;
        DestBitmapBytes = NULL;
        if (OutputPalette != NULL)
        {
            CCFree(OutputPalette);
            OutputPalette = NULL;
        }
    }

    return ok;
}
Exemplo n.º 16
0
BOOL OutputPNG::WriteBlock( UINT32 YPos, UINT32 Height, LPBYTE BlockStart, UINT32 InputBPP,
                            INT32 ProgressOffset)
{
    ERROR2IF(DestBitmapInfo == NULL, FALSE,"OutputPNG::WriteBlock destination bitmap info null");
    ERROR2IF(DestBitmapBytes == NULL, FALSE,"OutputPNG::WriteBlock destination bitmap bits null");
    ERROR2IF(pNextStrip == NULL, FALSE,"OutputPNG::WriteBlock next strip pointer is null");

    FNPTR_SCANLINE ConvertFn = NULL;
    LPBYTE Buffer = NULL;
    size_t BufSize = 0L;
    size_t ChunkHeight = 1;
    DIBConvert *DoConvert = NULL;

    // Set up the size and other information for the dib block that we require. This is
    // dependent on the export depth or bpp required.
    if ( !SetUpBlock( &BufSize, &ChunkHeight, &DoConvert, &ConvertFn ) )
        return FALSE;			// Error details already set up

    if (BufSize)
    {
        Buffer = (LPBYTE)CCMalloc( BufSize );
        if (Buffer==NULL)
            return FALSE;
    }

    if ( DoConvert )
    {
        // use new classes to do it
        // 8bpp, 4bpp and 1bpp conversion
        INT32 h = Height;
        INT32 count = 0;
        LPBYTE Data = BlockStart;
        const size_t SourceWidth = DIBUtil::ScanlineSize( BitmapInfo.biWidth, InputBPP ) * ChunkHeight;
        const size_t DestWidth   = DIBUtil::ScanlineSize( BitmapInfo.biWidth, BitmapInfo.biBitCount );

        while (h)
        {
            ENSURE(h >= 0, "bad looping");

            const size_t ThisBit = min( h, (INT32)ChunkHeight );
            if (!DoConvert->Convert( Data, Buffer, ThisBit, IsFirstStrip ))
                break;								// stop if conversion failed

            IsFirstStrip = FALSE;

            // Copy this block to our destination bitmap
            // pNextStrip should be pointing at the next place to copy the data to
            memcpy(pNextStrip, Buffer, ThisBit * DestWidth);

            Data += SourceWidth;
            h -= ThisBit;
            pNextStrip += ThisBit * DestWidth;

            // now update the progress display, started with CurrentExportSize
            // CurrentExport size is now the point to go from in the export
            count++;
            ContinueSlowJob( (INT32)(ProgressOffset + count) );
            //ContinueSlowJob( (INT32)(100*count/(Height)) );
        }
    }
    else if ( ConvertFn && Buffer )
    {
        // Write via conversion function
        // 24 bpp convert
        UINT32 h = Height;
        INT32 count = 0;
        LPBYTE Data = BlockStart;
        const size_t SourceWidth = DIBUtil::ScanlineSize( BitmapInfo.biWidth, InputBPP );

        while (h)
        {
            ConvertFn( BitmapInfo.biWidth, Data, Buffer );

            // Copy this block to our destination bitmap
            // pNextStrip should be pointing at the next place to copy the data to
            memcpy(pNextStrip, Buffer, BufSize);

            Data += SourceWidth;
            h -= ChunkHeight;
            pNextStrip += BufSize;

            // now update the progress display, started with CurrentExportSize
            // ProgressOffset size is now the point to go from in the export
            count++;
            ContinueSlowJob( (INT32)( ProgressOffset + count ));
            //ContinueSlowJob( (INT32)((CurrentExportSize * count)/Height) );
        }
    }
    else
    {
        // Write the actual bytes out to file. Used to do it in one go but we really
        // require some progress bar indication so we will do it in chunks.
        DWORD BitsSize = BitmapInfo.biSizeImage;
        if (BitsSize > 0)
        {
            if (BitsSize < 1024)
            {
                // File very small or no progress bar required, so load in one go
                // Copy this block to our destination bitmap
                // pNextStrip should be pointing at the next place to copy the data to
                memcpy(pNextStrip, BlockStart, BitsSize);
                pNextStrip += BitsSize;
            }
            else
            {
                // Load in chunks, for present split into 100 chunks
                DWORD ChunkSize = BitsSize/100;
                DWORD Position = 0;
                LPBYTE pBitInfo = BlockStart;

                while (Position < BitsSize)
                {
                    if ( (BitsSize - Position) > ChunkSize)
                    {
                        // Copy this block to our destination bitmap
                        // pNextStrip should be pointing at the next place to copy the data to
                        memcpy(pNextStrip, pBitInfo, ChunkSize);
                    }
                    else
                    {
                        ChunkSize = BitsSize - Position;
                        // Copy this block to our destination bitmap
                        // pNextStrip should be pointing at the next place to copy the data to
                        memcpy(pNextStrip, pBitInfo, ChunkSize);
                    }

                    // Increment our counters/pointers
                    Position+=ChunkSize;
                    pBitInfo+=ChunkSize;
                    pNextStrip += ChunkSize;
                    // Progress bar started with height of bitmap
                    ContinueSlowJob( (INT32)(ProgressOffset + (Height * Position)/BitsSize) );
                    //ContinueSlowJob( (INT32)((CurrentExportSize * Position)/BitsSize) );
                }
            }
        }
    }

    // If present, get rid of our export function
    if (DoConvert)
    {
        delete DoConvert;
        DoConvert = NULL;
    }

    CCFree( Buffer );

    HeightWritten += Height;						// remember we wrote this lot

    return TRUE;
}
Exemplo n.º 17
0
BOOL OutputDIB::StartFile( CCLexFile *File, LPBITMAPINFOHEADER lpHeader, LPLOGPALETTE Palette,
						   UINT32 OutputDepth, DWORD CompressionType,
						   UINT32 FinalHeight, INT32 ExportSize, BOOL SecondPass,
						   UINT32 DitherType )
{
	// remember input args
	OutputFile = File;
	StartPos = OutputFile->tell();						// remember where in the file this starts
	BitmapInfo = *lpHeader;								// take a copy of user's header
	OutputPalette = NULL;								// our form of the palette, if required

	HeightWritten = 0;									// our count of the bitmap lines written
	CurrentExportSize = ExportSize;						// size set up for the progress bar
	HeightWanted = FinalHeight;							// the actual height of the export required

	INT32 PalSize = 0;									// how many entries in palette

	// Remember which dithering type to use
	Dither = DitherType;

	IsFirstStrip = TRUE;

	// Set up the information header for the dib
	if ( !SetUpInfoHeader(lpHeader, OutputDepth, CompressionType, FinalHeight, &PalSize) )
		return FALSE;									// SetError already called 

	// BITMAPFILEHEADER goes first
	BITMAPFILEHEADER Header;

	Header.bfType = ('M'<<8) | 'B';
	Header.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) +
					sizeof(RGBQUAD)*PalSize + BitmapInfo.biSizeImage;
	Header.bfReserved1 = 0;
	Header.bfReserved2 = 0;
	Header.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) +
						sizeof(RGBQUAD)*PalSize;

	OutputFile->write( &Header, sizeof(Header) );


	// then a local BITMAPINFOHEADER

	OutputFile->write( &BitmapInfo, sizeof(BITMAPINFOHEADER) );

	// then the RGBQUAD palette
	if (PalSize)
	{
		ERROR2IF(Palette == NULL,FALSE,"StartFile has a NULL Palette when one is required");
		// make a copy of the palette for possible later use
		const size_t TotalPal = sizeof(LOGPALETTE) + ( sizeof(PALETTEENTRY) * PalSize );
		OutputPalette = (LPLOGPALETTE)CCMalloc( TotalPal );
		if (OutputPalette==NULL)
			return FALSE;

		// Take a copy of that palette
		memcpy( OutputPalette, Palette, TotalPal );

		// write it to disk in RGBQUAD format
		RGBQUAD TempRGB;
		TempRGB.rgbReserved = 0;
		for (INT32 i=0; i<PalSize; i++)
		{
			TempRGB.rgbRed = OutputPalette->palPalEntry[i].peRed;
			TempRGB.rgbGreen = OutputPalette->palPalEntry[i].peGreen;
			TempRGB.rgbBlue = OutputPalette->palPalEntry[i].peBlue;
			OutputFile->write( &TempRGB, sizeof(RGBQUAD) );
		}
	}

	return !OutputFile->bad();
}
Exemplo n.º 18
0
BOOL GIFUtil::ReadFromFile( CCLexFile *File, LPBITMAPINFO *Info, LPBYTE *Bits,
							int *TransColour, int& nBitmapToRead, String_64 *ProgressString,
							BaseCamelotFilter *pFilter, UINT32* Delay, GIFDisposalMethod *Restore,
							UINT32 * pLeftOffset, UINT32 * pTopOffset,
							BOOL * pLocalPalette)
{
	if ((nBitmapToRead > 1 && nBitmapToRead == m_nCurrentBitmap) || nBitmapToRead < 1)
	{
		ERROR3("GIFUtil::ReadFromFile() - can't read that bitmap");
		return FALSE;
	}

	*Info			= NULL;		// in case of early exit
	*Bits			= NULL;
	Transparent 	= -1;
	*TransColour 	= -1;		// in case of early exit set to none
	int Background 	= 0;		// background colour number !!! not used !!!
	Interlace 		= FALSE;	// set interlace to false by default

	// Must set the exception throwing flag to True and force reporting of errors to False.
	// This means that the caller must report an error if the function returns False.
	// Any calls to CCLexFile::GotError will now throw a file exception and should fall into
	// the catch handler at the end of the function.
	BOOL OldThrowingState = File->SetThrowExceptions( TRUE );
	BOOL OldReportingState = File->SetReportErrors( FALSE );

	// If the caller has specified a string then assume they require a progress bar
	// Start it up.
	if (ProgressString != NULL)
		BeginSlowJob(100, FALSE, ProgressString);

	try
	{
		// If we want the first bitmap we'll assume we're at the start of the file & read the header
		if (nBitmapToRead == 1)
		{
			// place to store the global palette, if present, for later use
			lpGlobalPalette 		= NULL;	// pointer to temporary palette store
			GlobalPaletteSize 			= 0;	// size of the global palette found	 

			GIFINFOHEADER Header;
			// This is really sizeof(GIFINFOHEADER) but this returns 14 instead of 13
			// as it rounds to the nearest word boundary
			const size_t HeaderSize = sizeof(char)* 6 + sizeof(WORD) * 2 + sizeof(BYTE) * 3;

			File->read( &Header, HeaderSize );
			if (File->bad())
				File->GotError( _R(IDE_FORMATNOTSUPPORTED) );

			// Just double check that the signature is correct, if not then fail immediately
			if (
				(strncmp(Header.giName, "GIF89a", 6) != 0) &&
	 			(strncmp(Header.giName, "GIF87a", 6) != 0)
			)
				File->GotError( _R(IDE_BADFORMAT) );

			// Note the overall size of the GIF from the header, may be the animation size
			m_GlobalWidth		= Header.giWidth;
			m_GlobalHeight  	= Header.giHeight;
			// flags word consists of:-
			// - bit 7 colour table flag				= set if global colour table follows
			// - bits 6-4 colour resolution				= bpps - 1
			// - bit 3 sort flag						= set global colour table sorted
			// - bits 3-0 size of global colour table 	= size is 2^(value+1)
			int ColorResolution = (((Header.giFlags >> 4) & 0x07) + 1);
			GlobalPaletteSize	= 2 << (Header.giFlags & 0x07);
			Background			= Header.giBackground;
//			int AspectRatio		= Header.giAspect;

TRACEUSER("Neville",_T("Gif Global Width = %d Height = %d\n"), m_GlobalWidth, m_GlobalHeight);
TRACEUSER("Neville",_T("Gif ColorResolution = %d\n"), ColorResolution);

			// Check if we have a global colour map present or not, if so then read it in.
			if (BitSet(Header.giFlags, GLOBALCOLOURMAP))
			{
TRACEUSER("Neville",_T("Gif read global colour table size = %d\n"), GlobalPaletteSize);
			    // Read in the global colour map into a palette structure for possible later use
				const size_t TotalPal = sizeof(RGBQUAD) * GlobalPaletteSize;
				lpGlobalPalette = (LPRGBQUAD)CCMalloc( TotalPal );
				if (lpGlobalPalette==NULL)
					return FALSE;

				ReadColourMap(File, GlobalPaletteSize, lpGlobalPalette);
			}
			m_nCurrentBitmap = 0;
			m_NextImageStartPosition = 0;
		}

		// We now need to go through and process the data in this file which
		// should now consist off GIF blocks until we hit the end of file or
		// we have processed the lot.
		BOOL FileProcessed = FALSE;

		m_bImageRead = FALSE;
		unsigned char c;
		// Set up bad values so that the DIB alloc claim will fail if there
		// has been no GIFIMAGEBLOCK found
//		int	Width 		  	= 0;	// Width of bitmap	
//		int Height 		  	= 0;	// Height of bitmap	
//		int BitsPerPixel	= 0;	//ColorResolution;	// Colour depth required

		if (m_NextImageStartPosition != 0)
		{
			File->seekIn(m_NextImageStartPosition, ios::beg);
			m_NextImageStartPosition = 0;
		}

		while (!File->eof() && !File->bad() && !FileProcessed)
		{
			// Get the next character in the stream and see what it indicates
			// comes next in the file
			// Use Get as this will read the EOF character (255) and exit via the
			// File->eof() test rather than Read which will throw an exception. 
			//File->read( &c, 1 );
			File->get( (char&)c );
			
			switch (c)
			{
				case ';':
				{
					// GIF terminator
					// Cannot assume that the terminator immediately follows the image data
					// Might have some extensions following the image data. 					 
					FileProcessed = TRUE;
					nBitmapToRead = -1;
					break;
				}

				case '!': //EXTENSIONBLOCK:
				{
					// Extension
					ProcessExtension(File);
					break;
				}
				
				case ',':
				{
					// start of image character
					if (m_bImageRead)	// another bitmap - save it for the next call to ReadFromFile()
					{
						if (m_NextImageStartPosition == 0)
						{
							// No transparency info for the next one so start here
							m_NextImageStartPosition = File->tellIn() - 1;
						}
						++nBitmapToRead;
						FileProcessed = TRUE;
						break;
					}

					UINT32 LeftOffset = 0;
					UINT32 TopOffset = 0;
					BOOL LocalPalette = FALSE;

					// Should be followed by a GIFIMAGE BLOCK
					ProcessImageBlock(File, Info, Bits, &LeftOffset, &TopOffset, &LocalPalette);
					++m_nCurrentBitmap;

					if (nBitmapToRead == m_nCurrentBitmap)
					{
						m_bImageRead = TRUE;
					}

					// return the values back to the caller if it desired them
					if (pLeftOffset)
						*pLeftOffset = LeftOffset;
					if (pTopOffset)
						*pTopOffset = TopOffset;
					if (pLocalPalette)
						*pLocalPalette = LocalPalette;
					break;
				}

				default:
					// We have found something other than what we are expecting
					// so fail with an error
					//File->GotError( IDE_BADFORMAT );
					// Cannot do this as some files have random bits
					// e.g. galileo.gif has a random zero before the ;
					//     	colsec.gif has a rampant > at the end instead of ;
					if (m_bImageRead)
					{
						// We've already got something so ignore anything else in case it goes
						// completely wrong.
						FileProcessed = TRUE;
						nBitmapToRead = -1;
					}
					TRACE( _T("Unrecognized Character %x at %d\n"), (int)c, File->tellIn());

					break;
			}
		}

		// If we reach here and the bitmap allocations are still null then no valid image
		// was found and so we should error now.
		// Might have just been a GIF file with extension tags in and no images!
		if (*Info == NULL || *Bits == NULL)
			File->GotError( _R(IDE_BADFORMAT) );

		// We read the desired bitmap but the EOF came along before we could try anything else
		// Signal this is the last bitmap
		if (m_bImageRead && File->eof())
		{
			TRACE( _T("GIF: Premature end of file") );
			nBitmapToRead = -1;
		}

		// Return the transparency/delay/restore found to the caller.
		*TransColour = Transparent;
		if (Delay)
		{
			*Delay = m_Delay;
		}
		if (Restore)
		{
			*Restore = m_Restore;
		}

		// Free up the bit of memory for a palette we grabbed, if present & no more images to read
		if (lpGlobalPalette && nBitmapToRead == -1)
		{
			CCFree(lpGlobalPalette);
			lpGlobalPalette = NULL;
		}

		// If started, then stop then progress bar
		if (ProgressString != NULL)
			EndSlowJob();

		// Must set the exception throwing and reporting flags back to their entry states
		File->SetThrowExceptions( OldThrowingState );
		File->SetReportErrors( OldReportingState );

		// er, we seem to have finished OK so say so
		return TRUE;
	}
Exemplo n.º 19
0
BOOL OutputDIB::SetUpExport( CCLexFile *File, LPBITMAPINFOHEADER lpHeader, LPLOGPALETTE Palette,
							 UINT32 DitherType, UINT32 OutputDepth, DWORD CompressionType, UINT32 FinalHeight,
							 LPBYTE BlockStart, UINT32 StripSize, INT32 ExportSize, BOOL Forward )
{
	ERROR2IF(File==NULL, FALSE, "OutputDIB::SetUpExport null File specified");
	ERROR2IF(lpHeader==NULL, FALSE, "OutputDIB::SetUpExport null lpHeader specified");
	ERROR2IF(BlockStart==NULL, FALSE, "OutputDIB::SetUpExport null BlockStart specified");

	// remember input args
	OutputFile = File;
	StartPos = OutputFile->tell();						// remember where in the file this starts
	BitmapInfo = *lpHeader;								// take a copy of user's header
	OutputPalette = NULL;								// No palette to start with
	HeightWritten = 0;									// zero height
	OutputForward = Forward;							// Note the output direction
	CurrentStripSize = StripSize;						// Note size of first strip
	CurrentExportSize = ExportSize;						// size set up for the progress bar
	HeightWanted = FinalHeight;							// the actual height of the export required

	// Remember which dithering type to use
	Dither = DitherType;

	IsFirstStrip = TRUE;

	ExportBuffer = NULL;	// Just in case of early random exit set this to NULL

	INT32 PalSize = 0;									// how many entries in palette

	// Set up the information header for the dib
	if ( !SetUpInfoHeader(lpHeader, OutputDepth, CompressionType, FinalHeight, &PalSize) )
		return FALSE;									// SetError already called 

	// then the RGBQUAD palette, if required
	if (PalSize)
	{
		ERROR2IF(Palette == NULL,FALSE,"SetUpExport has a NULL Palette when one is required");
		// If we are creating a palette then the Accusoft code requires that we specify an
		// bitmap info header which is followed immediately in memory by the palette.
		// if we just created a Palette then this would not be true so we must create a
		// new copy of the Bitmapinfo and then create the palette next.
		// This will not work in debug builds due to memory tracking information stored
		// in the allocation so we must allocate one big block and do the info header and
		// Palette from these.
		const size_t TotalHeader = sizeof(BITMAPINFOHEADER); 
		const size_t TotalPalSize = (sizeof(RGBQUAD) * PalSize );
		lpBitmap = (LPBITMAPINFO)CCMalloc( TotalHeader + TotalPalSize );
		if (lpBitmap==NULL)
			return FALSE;

		// make a copy of the palette for possible later use
		const size_t TotalPal = sizeof(LOGPALETTE) + ( sizeof(PALETTEENTRY) * PalSize );
		
		OutputPalette = (LPLOGPALETTE)CCMalloc( TotalPal );
		if (OutputPalette==NULL)
			return FALSE;
		memcpy( OutputPalette, Palette, TotalPal );
		
		// These are all freed in the TidyUp call.

		// Take a copy of the bitmap info header
		lpBitmapInfo = &(lpBitmap->bmiHeader);				// pointer to info header
		memcpy( lpBitmapInfo, &BitmapInfo, TotalHeader );	// copy header info across

		// Now get a pointer to the palette
		LPRGBQUAD lpPalette = NULL;
		lpPalette = &(lpBitmap->bmiColors[0]);				// pointer to colours table

		// Now copy the palette across into the bitmap info structure in RGQUAD form
		// OutputPalette should be set up by now so use this instead of Palette so if
		// we have bodged it, it will be the correct bodged palette that is put into the file
		// and not the 256 entry palette that seems to be supplied always.

		//  We might want to use the existing palette - e.g. when we are altering the value
		//  of a single colour.
			//  Don't want to use the existing palette.
		for (INT32 i = 0; i < PalSize; i++)
		{
			lpPalette->rgbRed	= OutputPalette->palPalEntry[i].peRed;
			lpPalette->rgbGreen = OutputPalette->palPalEntry[i].peGreen;
			lpPalette->rgbBlue	= OutputPalette->palPalEntry[i].peBlue;
			
			lpPalette++;
		}

	}

	// Now lets grab the memory and then set up the first block of data ready for output
	size_t BufSize = 0L;
	ExportChunkHeight = 1;

	DoExportConvert = NULL;		// Just in case the SetUpBlock fails 
	ExportConvertFn = NULL;		// Just in case the SetUpBlock fails
	
	// Set up the size and other information for the dib block that we require. This is
	// dependent on the export depth or bpp required.
	if ( !SetUpBlock( &BufSize, &ExportChunkHeight, &DoExportConvert, &ExportConvertFn ) )
		return FALSE;			// Error details already set up

//TRACEUSER( "Neville", _T("SetUpExport BufSize = %d\n"),BufSize);
//TRACEUSER( "Neville", _T("SetUpExport ExportChunkHeight = %d\n"),ExportChunkHeight);
//TRACEUSER( "Neville", _T("SetUpExport FinalHeight = %d\n"),FinalHeight);
//TRACEUSER( "Neville", _T("SetUpExport CurrentStripSize = %d\n"),CurrentStripSize);
//TRACEUSER( "Neville", _T("SetUpExport DoExportConvert = %d\n"),DoExportConvert);
//TRACEUSER( "Neville", _T("SetUpExport ExportConvertFn = %d\n"),ExportConvertFn);

	// Check for the case where we are exporting a small thin strip which is smaller
	// than our normal strip  
	if (CurrentStripSize < ExportChunkHeight)
	{
		ExportChunkHeight = CurrentStripSize;
//TRACEUSER( "Neville", _T("New ExportChunkHeight = %d\n"),ExportChunkHeight);
	}

	if (BufSize)
	{
		ExportBuffer = (LPBYTE)CCMalloc( BufSize );
		if (ExportBuffer==NULL)
			return FALSE;
	}
	
	// Now get the actual class variables set up ready for this data
	SetUpForNextStrip(BlockStart, CurrentStripSize);

	// Now lets start the whole export process off by calling the StartSaveBitmap function
	// which will start the actual exporting process off with the supplied information.
	// This will then request blocks of data from the DestDIB in its call back routine
	// get_dib_data.

	// If we have created a palette then use the special header which has a valid palette
	// following immediately after it in memory
	LPBITMAPINFOHEADER lpSpBitmapInfo = NULL;
	if (PalSize)
		lpSpBitmapInfo = lpBitmapInfo;		// Use our specially create header followed by palette
	else
		lpSpBitmapInfo = &BitmapInfo;		// Use the proper header defined in the class

#ifndef WEBSTER
	//WEBSTER-Martin-07/01/97
	// no Accusoft stuff in WEBSTER, and I'm not sure it ever gets used in Camelot any
	// more (the DIB bits of Accusoft that is)
	// TRACEUSER( "Martin", _T("Not allowed to use Accusoft save bitmap\n"));
	if (!AccusoftFilters::StartSaveBitmap(	OutputFile,		// File to use
											lpSpBitmapInfo,	// pointer to info header
											OutputPalette,	// pointer to the palette
											OutputDepth,	// actual file depth
											BI_RGB,			// compression (BI_RGB = none)
											FinalHeight,	// all of it
											StripSize,		// size of the strip, might be FinalHeight
											OutputForward)	// direction we were told on entry
	   )
#endif //WEBSTER
	{
		return FALSE;	//always for WEBSTER
	}

	return TRUE;
}