/* * polytoregion * * Scan converts a polygon by returning a run-length * encoding of the resultant bitmap -- the run-length * encoding is in the form of an array of rectangles. */ Region XPolygonRegion( XPoint *Pts, /* the pts */ int Count, /* number of pts */ int rule) /* winding rule */ { Region region; register EdgeTableEntry *pAET; /* Active Edge Table */ register int y; /* current scanline */ register int iPts = 0; /* number of pts in buffer */ register EdgeTableEntry *pWETE; /* Winding Edge Table Entry*/ register ScanLineList *pSLL; /* current scanLineList */ register XPoint *pts; /* output buffer */ EdgeTableEntry *pPrevAET; /* ptr to previous AET */ EdgeTable ET; /* header node for ET */ EdgeTableEntry AET; /* header node for AET */ EdgeTableEntry *pETEs; /* EdgeTableEntries pool */ ScanLineListBlock SLLBlock; /* header for scanlinelist */ int fixWAET = FALSE; POINTBLOCK FirstPtBlock, *curPtBlock; /* PtBlock buffers */ POINTBLOCK *tmpPtBlock; int numFullPtBlocks = 0; if (! (region = XCreateRegion())) return (Region) NULL; /* special case a rectangle */ pts = Pts; if (((Count == 4) || ((Count == 5) && (pts[4].x == pts[0].x) && (pts[4].y == pts[0].y))) && (((pts[0].y == pts[1].y) && (pts[1].x == pts[2].x) && (pts[2].y == pts[3].y) && (pts[3].x == pts[0].x)) || ((pts[0].x == pts[1].x) && (pts[1].y == pts[2].y) && (pts[2].x == pts[3].x) && (pts[3].y == pts[0].y)))) { region->extents.x1 = min(pts[0].x, pts[2].x); region->extents.y1 = min(pts[0].y, pts[2].y); region->extents.x2 = max(pts[0].x, pts[2].x); region->extents.y2 = max(pts[0].y, pts[2].y); if ((region->extents.x1 != region->extents.x2) && (region->extents.y1 != region->extents.y2)) { region->numRects = 1; *(region->rects) = region->extents; } return(region); } if (Count < 2) return region; if (! (pETEs = Xmalloc(sizeof(EdgeTableEntry) * Count))) { XDestroyRegion(region); return (Region) NULL; } pts = FirstPtBlock.pts; CreateETandAET(Count, Pts, &ET, &AET, pETEs, &SLLBlock); pSLL = ET.scanlines.next; curPtBlock = &FirstPtBlock; if (rule == EvenOddRule) { /* * for each scanline */ for (y = ET.ymin; y < ET.ymax; y++) { /* * Add a new edge to the active edge table when we * get to the next edge. */ if (pSLL != NULL && y == pSLL->scanline) { loadAET(&AET, pSLL->edgelist); pSLL = pSLL->next; } pPrevAET = &AET; pAET = AET.next; /* * for each active edge */ while (pAET) { pts->x = pAET->bres.minor_axis, pts->y = y; pts++, iPts++; /* * send out the buffer */ if (iPts == NUMPTSTOBUFFER) { tmpPtBlock = Xmalloc(sizeof(POINTBLOCK)); curPtBlock->next = tmpPtBlock; curPtBlock = tmpPtBlock; pts = curPtBlock->pts; numFullPtBlocks++; iPts = 0; } EVALUATEEDGEEVENODD(pAET, pPrevAET, y); } (void) InsertionSort(&AET); } } else { /* * for each scanline */ for (y = ET.ymin; y < ET.ymax; y++) { /* * Add a new edge to the active edge table when we * get to the next edge. */ if (pSLL != NULL && y == pSLL->scanline) { loadAET(&AET, pSLL->edgelist); computeWAET(&AET); pSLL = pSLL->next; } pPrevAET = &AET; pAET = AET.next; pWETE = pAET; /* * for each active edge */ while (pAET) { /* * add to the buffer only those edges that * are in the Winding active edge table. */ if (pWETE == pAET) { pts->x = pAET->bres.minor_axis, pts->y = y; pts++, iPts++; /* * send out the buffer */ if (iPts == NUMPTSTOBUFFER) { tmpPtBlock = Xmalloc(sizeof(POINTBLOCK)); curPtBlock->next = tmpPtBlock; curPtBlock = tmpPtBlock; pts = curPtBlock->pts; numFullPtBlocks++; iPts = 0; } pWETE = pWETE->nextWETE; } EVALUATEEDGEWINDING(pAET, pPrevAET, y, fixWAET); } /* * recompute the winding active edge table if * we just resorted or have exited an edge. */ if (InsertionSort(&AET) || fixWAET) { computeWAET(&AET); fixWAET = FALSE; } } } FreeStorage(SLLBlock.next); (void) PtsToRegion(numFullPtBlocks, iPts, &FirstPtBlock, region); for (curPtBlock = FirstPtBlock.next; --numFullPtBlocks >= 0;) { tmpPtBlock = curPtBlock->next; Xfree(curPtBlock); curPtBlock = tmpPtBlock; } Xfree(pETEs); return(region); }
ubyte *lzw_expand( ubyte *inputbuf, ubyte *outputbuf, int length ) { BIT_BUF *input; unsigned int new_code; unsigned int old_code; int character; unsigned int count; int counter; input = OpenInputBitBuf( inputbuf ); if ( outputbuf == NULL ) outputbuf = (ubyte *)malloc(length*sizeof(ubyte)); InitializeStorage(); counter = 0; for ( ; ; ) { InitializeDictionary(); old_code = (unsigned int) InputBits( input, current_code_bits ); if ( old_code == END_OF_STREAM ) { CloseInputBitBuf( input ); return outputbuf; } character = old_code; if (counter<length) { outputbuf[counter++] = ( ubyte ) old_code; } else { //printf( "ERROR:Tried to write %d\n", old_code ); //exit(1); return 0; } for ( ; ; ) { new_code = (unsigned int) InputBits( input, current_code_bits ); if ( new_code == END_OF_STREAM ) { CloseInputBitBuf( input ); FreeStorage(); return outputbuf; } if ( new_code == FLUSH_CODE ) break; if ( new_code == BUMP_CODE ) { current_code_bits++; continue; } if ( new_code >= next_code ) { decode_stack[ 0 ] = (char) character; count = decode_string( 1, old_code ); } else { count = decode_string( 0, new_code ); } character = decode_stack[ count - 1 ]; while ( count > 0 ) { // This lets the case counter==length pass through. // This is a hack. if (counter<length) { //printf("%x ", ( ubyte ) decode_stack[ count ]); outputbuf[counter++] = ( ubyte ) decode_stack[ --count ]; } else if (counter>length) { printf( "ERROR:Tried to write %d\n", decode_stack[ --count ] ); exit(1); } else count--; } dict[ next_code ].parent_code = old_code; dict[ next_code ].character = (char) character; next_code++; old_code = new_code; } } }
ByteBuffer::~ByteBuffer() { FreeStorage(); }
ubyte *lzw_compress( ubyte *inputbuf, ubyte *outputbuf, int input_size, int *output_size ) { BIT_BUF *output; int character; int string_code; unsigned int index; int i; output = OpenOutputBitBuf(); if ( outputbuf == NULL ) { output->buf = (ubyte *)malloc(input_size*sizeof(ubyte)); if (output->buf == NULL) { //printf(" ERROR : OpenOutputBitBuf - Not enough memory to read buffer.\n"); //exit(1); return NULL; } outputbuf = output->buf; } else { output->buf = outputbuf; } InitializeStorage(); InitializeDictionary(); string_code = ( *inputbuf++ ); for ( i=0 ; i<input_size ; i++ ) { if (output->current_byte+4 >= input_size) { CloseOutputBitBuf( output ); FreeStorage(); free( outputbuf ); *output_size = -1; return NULL; } character = ( *inputbuf++ ); index = find_child_node( string_code, character ); if ( dict[ index ].code_value != - 1 ) { string_code = dict[ index ].code_value; } else { dict[ index ].code_value = next_code++; dict[ index ].parent_code = string_code; dict[ index ].character = (char) character; OutputBits( output,(unsigned long) string_code, current_code_bits ); string_code = character; if ( next_code > MAX_CODE ) { OutputBits( output,(unsigned long) FLUSH_CODE, current_code_bits ); InitializeDictionary(); } else if ( next_code > next_bump_code ) { OutputBits( output,(unsigned long) BUMP_CODE, current_code_bits ); current_code_bits++; next_bump_code <<= 1; next_bump_code |= 1; } } } OutputBits( output, (unsigned long) string_code, current_code_bits ); OutputBits( output, (unsigned long) END_OF_STREAM, current_code_bits); *output_size = output->current_byte + 1; CloseOutputBitBuf( output ); FreeStorage(); return outputbuf; }