#include "xieperf.h"
#include <stdio.h>
#define NTILES 16
#define SPLIT 4
static void InitSegments ( void );
static void CloseSegments ( XParms xp, Parms p );
static int SegmentPhotomap ( XParms xp, Parms p, XiePhotomap pm,
XiePhotomap segvec[], int size, int split,
int width, int height );
static int BuildPasteUpFlograph ( XParms xp, Parms p,
XiePhotoElement **flograph,
XiePhotomap segments[], int size,
int split, int width, int height );
static int BuildMeSomeTiles ( XieTile tiles[], int split, int width,
int height, int method, int overlap );
static void SetTileXY ( XieTile tiles[], int split, int width, int height,
int method, int overlap );
static XieLut XIELut;
static XiePhotomap XIEPhotomap;
static XiePhotomap segments[NTILES];
static XieTile tiles[NTILES];
static XiePhotoElement *flograph;
static XiePhotoflo flo;
static int flo_elements;
static XieConstant constant = { 0.0, 0.0, 0.0 };
static int monoflag = 0;
static int pasteUpIdx;
int
InitPasteUp(XParms xp, Parms p, int reps)
{
XIEimage *image;
flograph = ( XiePhotoElement * ) NULL;
flo = ( XiePhotoflo ) NULL;
XIELut = ( XieLut ) NULL;
XIEPhotomap = ( XiePhotomap ) NULL;
InitSegments();
image = p->finfo.image1;
if ( !image )
reps = 0;
if ( reps )
{
monoflag = 0;
if ( xp->screenDepth != image->depth[ 0 ] )
{
monoflag = 1;
if ( ( XIELut = CreatePointLut( xp, p,
1 << image->depth[0],
1 << xp->screenDepth, False ) )
== ( XieLut ) NULL )
{
reps = 0;
}
}
}
if ( reps )
{
if ( ( XIEPhotomap = GetXIEPhotomap( xp, p, 1 ) ) ==
( XiePhotomap ) NULL )
{
reps = 0;
}
else if ( !SegmentPhotomap( xp, p, XIEPhotomap,
segments, NTILES, SPLIT, image->width[ 0 ],
image->height[ 0 ] ) )
{
reps = 0;
}
else if ( !BuildPasteUpFlograph( xp, p,
&flograph, segments, NTILES, SPLIT, image->width[ 0 ],
image->height[ 0 ] ) )
{
reps = 0;
}
}
if ( !reps )
FreePasteUpStuff( xp, p );
return( reps );
}
static void
InitSegments(void)
{
int i;
for ( i = 0; i < NTILES; i++ )
{
segments[ i ] = ( XiePhotomap ) NULL;
}
}
static void
CloseSegments(XParms xp, Parms p)
{
int i;
for ( i = 0; i < NTILES; i++ )
{
if ( segments[ i ] != ( XiePhotomap ) NULL )
{
XieDestroyPhotomap( xp->d, segments[ i ] );
segments[ i ] = ( XiePhotomap ) NULL;
}
}
}
static int
SegmentPhotomap(XParms xp, Parms p, XiePhotomap pm, XiePhotomap segvec[],
int size, int split, int width, int height)
{
int xoff, yoff;
int flo_elements;
XiePhotoElement *flograph;
int segidx;
XiePhotospace photospace;
XieEncodeTechnique encode_tech=xieValEncodeServerChoice;
char *encode_param=NULL;
float coefficients[ 6 ];
int i, retval;
XieGeometryTechnique sample_tech = xieValGeomNearestNeighbor;
char *sample_param = NULL;
unsigned long flo_id;
int piecewide, piecehigh;
retval = 1;
piecehigh = height / split;
piecewide = width / split;
photospace = XieCreatePhotospace(xp->d);
flo_elements = 3;
flograph = XieAllocatePhotofloGraph(flo_elements);
if ( flograph == ( XiePhotoElement * ) NULL )
{
fprintf( stderr, "XieAllocatePhotofloGraph failed\n" );
retval = 0;
}
if ( retval )
{
for ( i = 0; i < size; i++ )
{
if ( ( segments[ i ] = XieCreatePhotomap( xp->d ) ) ==
( XiePhotomap ) NULL )
{
fprintf( stderr,"XieCreatePhotomap failed\n" );
retval = 0;
}
}
}
if ( retval )
{
segidx = 0;
coefficients[ 0 ] = 1.0;
coefficients[ 1 ] = 0.0;
coefficients[ 2 ] = 0.0;
coefficients[ 3 ] = 1.0;
flo_id = 1;
for ( xoff = 0; xoff < width; xoff+= piecewide )
{
for (yoff = 0;yoff < width;yoff += piecehigh)
{
XieFloImportPhotomap( &flograph[ 0 ],
pm,
False );
coefficients[ 4 ] = (float) xoff;
coefficients[ 5 ] = (float) yoff;
XieFloGeometry( &flograph[ 1 ],
1,
piecewide,
piecehigh,
coefficients,
constant,
7,
sample_tech,
sample_param
);
XieFloExportPhotomap( &flograph[ 2 ],
2,
segvec[ segidx++ ],
encode_tech,
encode_param
);
XieExecuteImmediate(xp->d, photospace,
flo_id,
True,
flograph,
flo_elements
);
XSync( xp->d, 0 );
WaitForXIEEvent( xp, xieEvnNoPhotofloDone,
flo_id, 0, False );
flo_id++;
}
}
XieFreePhotofloGraph(flograph, flo_elements);
XieDestroyPhotospace(xp->d, photospace);
}
return( retval );
}
static int
BuildPasteUpFlograph(XParms xp, Parms p, XiePhotoElement **flograph,
XiePhotomap segments[], int size, int split,
int width, int height)
{
int i, flo_elements;
int tile_width, tile_height;
XieProcessDomain domain;
tile_width = width / split;
tile_height = height / split;
flo_elements = size + 2;
if ( monoflag )
flo_elements+=2;
*flograph = XieAllocatePhotofloGraph(flo_elements);
if ( *flograph == ( XiePhotoElement * ) NULL )
{
fprintf( stderr, "XieAllocatePhotofloGraph failed\n" );
return( 0 );
}
for ( i = 0; i < size; i++ )
{
XieFloImportPhotomap(&(*flograph)[i], segments[ i ], False);
}
if ( !BuildMeSomeTiles( tiles, split, tile_width, tile_height, 1,
( ( PasteUpParms * ) p->ts )->overlap ) )
return( 0 );
pasteUpIdx = size;
XieFloPasteUp( &(*flograph)[ size ], width, height, constant, tiles,
size );
if ( monoflag )
{
XieFloImportLUT(&(*flograph)[size + 1], XIELut );
domain.phototag = 0;
domain.offset_x = 0;
domain.offset_y = 0;
XieFloPoint(&(*flograph)[size + 2],
size + 1,
&domain,
size + 2,
0x7
);
}
XieFloExportDrawable(&(*flograph)[flo_elements - 1],
flo_elements - 1,
xp->w,
xp->fggc,
0,
0
);
flo = XieCreatePhotoflo( xp->d, *flograph, flo_elements );
return( 1 );
}
static int
BuildMeSomeTiles(XieTile tiles[], int split, int width, int height,
int method, int overlap)
{
int i, j, idx;
SetTileXY( tiles, split, width, height, method, overlap );
idx = 0;
for ( i = 0; i < split; i++ )
{
for ( j = 0; j < split; j++ )
{
tiles[ idx ].src = idx + 1;
idx++;
}
}
return( 1 );
}
static void
SetTileXY(XieTile tiles[], int split, int width, int height,
int method, int overlap)
{
int i, j, idx;
idx = 0;
if ( method == 0 )
{
for ( i = 0; i < split; i++ )
{
for ( j = 0; j < split; j++ )
{
if ( overlap == Overlap && i == j )
{
tiles[ idx ].dst_x = i * width - ( width / 2 );
tiles[ idx ].dst_y = j * height - ( height / 2 );
}
else
{
tiles[ idx ].dst_x = i * width;
tiles[ idx ].dst_y = j * height;
}
idx++;
}
}
}
else if ( method == 1 )
{
for ( i = 0; i < split; i++ )
{
for ( j = 0; j < split; j++ )
{
if ( overlap == Overlap && i == j )
{
tiles[ idx ].dst_x = j * width - ( width / 2 );
tiles[ idx ].dst_y = i * height - ( height / 2 );
}
else
{
tiles[ idx ].dst_x = j * width;
tiles[ idx ].dst_y = i * height;
}
idx++;
}
}
}
}
void
DoPasteUp(XParms xp, Parms p, int reps)
{
int i, method;
int flo_notify;
XIEimage *image;
int width, height, overlap;
flo_notify = True;
image = p->finfo.image1;
if ( !image )
return;
method = 0;
width = image->width[ 0 ];
height = image->height[ 0 ];
overlap = ( ( PasteUpParms * ) p->ts )->overlap;
for ( i = 0; i != reps; i++ )
{
XieExecutePhotoflo( xp->d, flo, flo_notify );
WaitForXIEEvent( xp, xieEvnNoPhotofloDone, flo, 0, False );
XSync( xp->d, 0 );
if ( i < reps )
{
XieFreePasteUpTiles(&flograph[ pasteUpIdx ] );
BuildMeSomeTiles( tiles, SPLIT, width / SPLIT,
height / SPLIT, method++, overlap );
if ( method == 2 )
method = 0;
XieFloPasteUp( &flograph[ pasteUpIdx ], width, height,
constant, tiles, NTILES );
XieModifyPhotoflo( xp->d, flo, pasteUpIdx + 1,
&flograph[pasteUpIdx], 1 );
XSync( xp->d, 0 );
}
}
}
void
EndPasteUp(XParms xp, Parms p)
{
FreePasteUpStuff( xp, p );
}
void
FreePasteUpStuff(XParms xp, Parms p)
{
XieFreePasteUpTiles(&flograph[ pasteUpIdx ] );
if ( XIELut )
{
XieDestroyLUT( xp->d, XIELut );
XIELut = ( XieLut ) NULL;
}
if ( XIEPhotomap && IsPhotomapInCache( XIEPhotomap ) == False )
{
XieDestroyPhotomap( xp->d, XIEPhotomap );
XIEPhotomap = ( XiePhotomap ) NULL;
}
CloseSegments( xp, p );
if ( flograph )
{
XieFreePhotofloGraph(flograph,flo_elements);
flograph = ( XiePhotoElement * ) NULL;
}
if ( flo )
{
XieDestroyPhotoflo( xp->d, flo );
flo = ( XiePhotoflo ) NULL;
}
}