Example #1
0
void mk_ramp(FBIO *fb, int r, int g, int b, int n)
{

    /* grey ramp */
    for (x=0; x < scr_width; ++x) {
	if (r) line[x*3] = rampval[x / patch_width + 1];
	else line[x*3] = 0;
	if (g) line[x*3+1] = rampval[x / patch_width + 1];
	else line[x*3+1] = 0;
	if (b) line[x*3+2] = rampval[x / patch_width + 1];
	else line[x*3+2] = 0;
    }
    for (y=patch_height*n; y < patch_height*(n+1) && y < scr_height; ++y) {
	fb_write(fb, 0, y, line, scr_width);
    }

    for (x=0; x < scr_width; ++x) {
	if (r) line[x*3] = rampval[x / patch_width];
	else line[x*3] = 0;
	if (g) line[x*3+1] = rampval[x / patch_width];
	else line[x*3+1] = 0;
	if (b) line[x*3+2] = rampval[x / patch_width];
	else line[x*3+2] = 0;
    }
    for (y=patch_height*(n+1); y < patch_height*(n+2) && y < scr_height; y += 2) {
	fb_write(fb, 0, y, altline, scr_width);
	fb_write(fb, 0, y+1, line, scr_width);
    }
}
Example #2
0
/*
 *	OutBuild - rasterize all strokes into raster frame image
 */
static bool
OutBuild(void)				/* returns true if successful */
{
    register struct band *hp;	/* *hp -> head of descr list */
    register struct band *np;	/* `hp' for next band */
    register stroke *vp;		/* -> rasterization descr */

    if ( single_banded ) {
	if ( debug ) fprintf(stderr, "OutBuild:  band y=%d\n", ystart);
	if ( fb_write( fbp, 0, ystart, buffer, buffersize/sizeof(RGBpixel) ) <= 0 )
	    return false;	/* can't write image file */
	if ( over )  {
	    /* Read back the composite image */
	    if ( fb_read( fbp, 0, ystart, buffer, buffersize/sizeof(RGBpixel) ) <= 0 )
		fprintf(stderr, "pl-fb:  band read error\n");
	}
	return true;
    }

    for ( hp = &band[0]; hp < bandEnd; ++hp )
	if ( hp->first != NULL )
	    break;

    if ( hp == bandEnd )
	return true;		/* nothing to do */

    for ( hp = &band[0], np = &band[1], ystart = 0;
	  hp < bandEnd;
	  hp = np++, ystart += lines_per_band
	)	{
	if (debug) fprintf(stderr, "OutBuild:  band y=%d\n", ystart);
	if ( over )  {
	    /* Read in current band */
	    if ( fb_read( fbp, 0, ystart, buffer, buffersize/sizeof(RGBpixel) ) <= 0 )
		fprintf(stderr, "pl-fb:  band read error\n");
	} else {
	    /* clear pixels in the band */
	    memset((char *)buffer, 0, buffersize);
	}

	while ( (vp = Dequeue( hp, &hp->first )) != NULL )
	    Raster( vp, np );      /* rasterize stroke */

	/* Raster() either re-queued the descriptor onto the
	   next band list or else it freed the descriptor */

	if (debug) fprintf(stderr, "OutBuild:  fbwrite y=%d\n", ystart);
	if ( fb_write( fbp, 0, ystart, buffer, buffersize/sizeof(RGBpixel) ) <= 0 )
	    return false;	/* can't write image file */
    }

    return true;			/* success */
}
Example #3
0
/** repeatText:
 *  Just prints a string of chars to the fb repeatedly,
 *  with a time waster to ensure all text doesn't immediately
 *  appear (for testing scrolling).
 *  Prints newlines first, then no newlines.
 */
void repeatText() {
	char test[] = "CirnOS is the strongest OS. \n";
	unsigned int i = 0;
	for(;i < 40; i++) {
		fb_write(test, 29);
		//waste time
		loop(1233356);
	}
	i = 0;
	for(;i < 40; i++) {
		fb_write(test, 28);
		//waste time
		loop(1233356);
	}	
}
Example #4
0
/*
 * Display the array v[Y][X] at screen location xoff, yoff.
 */
void
disp_array(long int (*v)[256], int xoff, int yoff)
{
    register int	x, y;
    static long	max;
    static double scale;
    unsigned char	obuf[256*3];

    /* Find max value */
    max = 0;
    for ( y = 0; y < 256; y++ ) {
	for ( x = 0; x < 256; x++ ) {
	    if ( v[y][x] > max )
		max = v[y][x];
	}
    }
    scale = 255.0 / ((double)max);

    /* plot them */
    for ( y = 0; y < 256; y++ ) {
	for ( x = 0; x < 256; x++ ) {
	    register int value;

	    value = v[y][x] * scale;
	    if ( value < THRESH && v[y][x] != 0 )
		value = THRESH;
	    obuf[x*3+RED] = obuf[x*3+GRN] = obuf[x*3+BLU] = value;
	}
	fb_write( fbp, xoff, yoff+y, obuf, 256 );
    }
}
Example #5
0
File: main.c Project: ismaellc/SOTR
// Bootstrap processor starts running C code here.
// Allocate a real stack and switch to it, first
// doing some setup required for memory allocator to work.
int
main(void)
{
	unsigned char FB[]="MESSAGE WRITTEN THROUGH FRAMEBUFFER!!";
	fb_init();       // initialize framebuffer device (2015.11.02)
	cprintf("\nUsing Framebuffer still presents some problems :(\n\n");
	cprintf("\nSuggestion: review the way it is used in console.c\n\n");
	fb_write(FB, sizeof(FB)); // Framebuffer maybe could be used before this moment (2015.11.02)
	see_mylock(MYLOCK);
  kinit1(end, P2V(4*1024*1024)); // phys page allocator
  kvmalloc();      // kernel page table
  mpinit();        // collect info about this machine
  lapicinit();
  seginit();       // set up segments
  cprintf("\ncpu%d: starting xv6\n\n", cpu->id);
  picinit();       // interrupt controller
  ioapicinit();    // another interrupt controller
  consoleinit();   // I/O devices & their interrupts
  uartinit();      // serial port
  pinit();         // process table
  tvinit();        // trap vectors
  binit();         // buffer cache
  fileinit();      // file table
  ideinit();       // disk
  if(!ismp)
    timerinit();   // uniprocessor timer
  startothers();   // start other processors
  kinit2(P2V(4*1024*1024), P2V(PHYSTOP)); // must come after startothers()
  userinit();      // first user process
  // Finish setting up this processor in mpmain.
  mpmain();
}
Example #6
0
static void
PutPixel(register int value)
{
    if ( pass == stop )
	Fatal(fbp, "Too much raster data for image size" );

    if ( value > entries )
	Fatal(fbp, "Decoded color index %d exceeds color map size", value );

    pixbuf[col*3+RED] = cmap[value][RED];	/* stuff pixel */
    pixbuf[col*3+GRN] = cmap[value][GRN];
    pixbuf[col*3+BLU] = cmap[value][BLU];

    if ( ++col == right )
    {
	/*
	  Note that BRL-CAD frame buffers are upside-down.
	  The following produces a right-side-up image at
	  the bottom of the available frame buffer.
	*/

	if ( fb_write( fbp, 0, ht - row, pixbuf, write_width ) < 0
	    )
	    Message( "Error writing scan line to frame buffer" );

	col = left;

	if ( (row += step[pass]) >= bottom
	     && ++pass < stop
	    )
	    row = start_row[pass];
    }
}
Example #7
0
void display()
{
    int	image = 0;

    tty_printf(" !!!  Processor %d running !!!\n", procid());

    while(image < NIMAGES)
    {
        while( buf_out_empty == TRUE ) {} // synchro

        tty_printf("\n *** starting display for image %d at cycle %d\n", image, proctime());
        if ( fb_write(0, buf_out, NLINES*NPIXELS) )
        {
                tty_printf("echec fb_sync_write\n");
                exit();
        }
        else
        {
            tty_printf("*** success fb_write ***\n");
        }

        if ( fb_completed() )
        {
            tty_printf("echec fb_completed\n");
            exit();
        }

        buf_out_empty = TRUE;

        tty_printf(" *** completing display for image %d at cycle %d\n", image, proctime());
        image++;
    } // end while image
    exit();
} // end display
Example #8
0
//main entry point for the kernel
int kmain() {
	setup_Com1();

	char doneText[] = "Done.\n";
	clearScreen(); //clear the screen of whatever was there

	//print welcome message
	char osVersion[] = "CirnOS v0.0.1\n";
	fb_write(osVersion, 14);
	
	//set up the GDT table
	char gdtSetup[] = "Setting up GDT...\n";
	fb_write(gdtSetup, 18);
	setupGDT();
	fb_write(doneText, 6);

	//set up IDT table
	char idtSetup[] = "Setting up IDT...\n";
	fb_write(idtSetup, 18);
	setupIDT();
	fb_write(doneText, 6);

	//Program Pic
	char picSetup[] = "Programming PIC...\n";
	fb_write(picSetup, 19);
	program_pic();
	fb_write(doneText, 6);

	char pagingSetup[] = "Setup PDT (identity, 4MB pages) and enabling paging...\n";
	fb_write(pagingSetup, 100);
	setup_pdt_enable_paging();
	fb_write(doneText, 6);

	char testStart[] = "Begining print tests.\n";
	fb_write(testStart, 22);

	//setup and write to Com1 serial port
	
	serial_write(osVersion, 14);
	serial_write(testStart, 21);
	char printfTest[] = "Printf test string: %c, %c, %d, %x.\n";
	printf(SERIAL, printfTest, 'c', 'd', -30, 0xCAFEBABE);
	printf(FRAMEBUFFER, printfTest, 'c', 'd', -30, 0xCAFEBABE);

	//repeatText(); //repeat some dummy text
	return 0; //return value will be in EAX register, return 0 for now
}
Example #9
0
// Write a positive decimal integer to the screen.
void fb_putui(unsigned int i) {
	if (i == 0) {
		fb_putc('0');
		return;
	}
	char c[32];
	itoa(i,c);
	fb_write(c);
}
Example #10
0
void
paintCellFb(struct application *ap, unsigned char *pixpaint, unsigned char *pixexpendable)
{
    int gx, gy;
    int gyfin, gxfin;
    int gxorg, gyorg;
    int x, y;
    int cnt;
#if DEBUG_CELLFB
    brst_log("paintCellFb: expendable {%d, %d, %d}\n",
	     pixexpendable[RED],
	     pixexpendable[GRN],
	     pixexpendable[BLU]);
#endif
    gridToFb(ap->a_x, ap->a_y, &gx, &gy);
    gxorg = gx+1;
    gyorg = gy+1;
    gxfin = zoom == 1 ? gx+zoom+1 : gx+zoom;
    gyfin = zoom == 1 ? gy+zoom+1 : gy+zoom;
    cnt = gxfin - gxorg;
    for (y = gyorg; y < gyfin; y++) {
	if (zoom != 1 && (y - gy) % zoom == 0)
	    continue;
	bu_semaphore_acquire(RT_SEM_STATS);
	(void) fb_read(fbiop, gxorg, y, (unsigned char *)pixbuf, cnt);
	bu_semaphore_release(RT_SEM_STATS);
	for (x = gxorg; x < gxfin; x++) {
	    if (SAMERGB(&pixbuf[x-gxorg][0], pixexpendable)
		) {
#if DEBUG_CELLFB
		brst_log("Clobbering:<%d, %d>{%d, %d, %d}\n",
			 x, y,
			 pixbuf[x-gxorg][RED],
			 pixbuf[x-gxorg][GRN],
			 pixbuf[x-gxorg][BLU]);
#endif
		COPYRGB(&pixbuf[x-gxorg][0], pixpaint);
	    }
#if DEBUG_CELLFB
	    else
		brst_log("Preserving:<%d, %d>{%d, %d, %d}\n",
			 x, y,
			 pixbuf[x-gxorg][RED],
			 pixbuf[x-gxorg][GRN],
			 pixbuf[x-gxorg][BLU]);
#endif
	}
	bu_semaphore_acquire(RT_SEM_STATS);
	(void) fb_write(fbiop, gxorg, y, (unsigned char *)pixbuf, cnt);
	bu_semaphore_release(RT_SEM_STATS);
#if DEBUG_CELLFB
	brst_log("paintCellFb: fb_write(%d, %d)\n", x, y);
#endif
    }
    return;
}
Example #11
0
void
paintGridFb()
{
    int fx, fy;
    int fxbeg, fybeg;
    int fxfin, fyfin;
    int fxorg, fyorg;
    int fgridwid;
    if (fb_clear(fbiop, pixbkgr) == -1)
	return;
    gridxmargin = (devwid - (gridwidth*zoom)) / 2.0;
    gridymargin = (devhgt - (gridheight*zoom)) / 2.0;
    gridToFb(gridxorg, gridyorg, &fxbeg, &fybeg);
    gridToFb(gridxfin+1, gridyfin+1, &fxfin, &fyfin);
    gridToFb(0, 0, &fxorg, &fyorg);
    CenterCell(fxorg); /* center of cell */
    CenterCell(fyorg);
    if (zoom == 1) {
	fgridwid = gridwidth + 2;
	fxfin++;
    } else
	fgridwid = gridwidth * zoom + 1;

    /* draw vertical lines */
    for (fx = 1; fx < fgridwid; fx++)
	COPYRGB(&pixbuf[fx][0], pixbkgr);
    for (fx = fxbeg; fx <= fxfin; fx += zoom)
	COPYRGB(&pixbuf[fx-fxbeg][0], &pixgrid[0]);
    for (fy = fybeg; fy <= fyfin; fy++)
	(void) fb_write(fbiop, fxbeg, fy, (unsigned char *)pixbuf, fgridwid);
    for (fy = 0; fy < devwid; fy++)
	(void) fb_write(fbiop, fxorg, fy, pixaxis, 1);

    /* draw horizontal lines */
    if (zoom > 1)
	for (fy = fybeg; fy <= fyfin; fy += zoom)
	    (void) fb_write(fbiop,
			    fxbeg, fy, pixgrid, fgridwid);
    for (fx = 0; fx < devwid; fx++)
	COPYRGB(&pixbuf[fx][0], pixaxis);
    (void) fb_write(fbiop, 0, fyorg, (unsigned char *)pixbuf, devwid);
    return;
}
Example #12
0
/*
 * Set/get the pixel value at position (x, y).
 *
 * Usage:
 * procname pixel x y [rgb]
 */
HIDDEN int
fbo_pixel_tcl(void *clientData, int argc, const char **argv)
{
    struct fb_obj *fbop = (struct fb_obj *)clientData;
    struct bu_vls vls = BU_VLS_INIT_ZERO;
    int x, y; 	/* pixel position */
    RGBpixel pixel;

    if (argc != 4 && argc != 5) {
	bu_log("ERROR: expecting five arguments\n");
	return BRLCAD_ERROR;
    }

    /* get pixel position */
    if (sscanf(argv[2], "%d", &x) != 1) {
	bu_log("fb_pixel: bad x value - %s", argv[2]);
	return BRLCAD_ERROR;
    }

    if (sscanf(argv[3], "%d", &y) != 1) {
	bu_log("fb_pixel: bad y value - %s", argv[3]);
	return BRLCAD_ERROR;
    }

    /* check pixel position */
    if (!fbo_coords_ok(fbop->fbo_fbs.fbs_fbp, x, y)) {
	bu_log("fb_pixel: coordinates (%s, %s) are invalid.", argv[2], argv[3]);
	return BRLCAD_ERROR;
    }

    /* get pixel value */
    if (argc == 4) {
	fb_rpixel(fbop->fbo_fbs.fbs_fbp, pixel);
	bu_vls_printf(&vls, "%d %d %d", pixel[RED], pixel[GRN], pixel[BLU]);
	Tcl_AppendResult(fbop->fbo_interp, bu_vls_addr(&vls), (char *)NULL);
	bu_vls_free(&vls);

	return BRLCAD_OK;
    }

    /*
     * Decompose the color list into its constituents.
     * For now must be in the form of rrr ggg bbb.
     */

    /* set pixel value */
    if (fbo_tcllist2color(argv[4], pixel) == BRLCAD_ERROR) {
	bu_log("fb_pixel: invalid color spec - %s", argv[4]);
	return BRLCAD_ERROR;
    }

    fb_write(fbop->fbo_fbs.fbs_fbp, x, y, pixel, 1);

    return BRLCAD_OK;
}
Example #13
0
static int fb_write_buffer(const uint8 *data, int len, int xlat) {
    int rv = len;

    (void)xlat;

    while(len--) {
        fb_write((int)(*data++));
    }

    return rv;
}
Example #14
0
/*
 *			V I E W _ E O L
 *
 *  Called by worker() at the end of each line.  Depricated.
 *  Any end-of-line processing should be done in view_pixel().
 */
void
view_eol(register struct application *ap)
{
    bu_semaphore_acquire( BU_SEM_SYSCALL );
    if ( outfp != NULL )
	fwrite( scanbuf, 1, width, outfp );
#if 0
    else if ( fbp != FBIO_NULL )
	fb_write( fbp, 0, ap->a_y, scanbuf, width );
#endif
    bu_semaphore_release( BU_SEM_SYSCALL );
}
Example #15
0
void kmain() {
	char bing[34] = "wowowow";
	char bong[50] = "JEJEJEJEJEJ";
	
	gdttable.address = (unsigned int)gdt_entries;
	gdttable.size = 24;
	load_gdt_entries();
	ggdt((unsigned int)&gdttable);
	
	serial_write(bong, SERIAL_COM1_BASE);
	fb_write(bing);
}
Example #16
0
__attribute__((constructor)) void display()
{
    char     byte;
    char     buf[NB_LINES][NB_PIXELS];
    int      base = 0;
    int      image = 0;
    int      npixels;      // number of pixels per processor      
    int      nblocks;       // number of blocks per processor



    npixels = NB_PIXELS*NB_LINES;
    nblocks = npixels/BLOCK_SIZE;

    // main loop
    while(1)
    {
        tty_printf("\n  *** image %d au cycle : %d *** \n", image, proctime());

        /* Phase 1 : lecture image sur le disque et transfert vers buf */
        if (ioc_read(base + nblocks, buf , nblocks))
        {
            tty_printf("\n!!! echec ioc_read au cycle : %d !!!\n", proctime()); 
            exit();
        }
        if ( ioc_completed() )
        {
            tty_printf("\n!!! echec ioc_completed au cycle : %d !!!\n", proctime());
            exit();
        }
        tty_printf("- image chargee au cycle = %d \n",proctime());

	tty_printf("test\n");
        /* Phase 3 : transfert de buf vers le frame buffer */
        if (fb_write(0,  buf, sizeof(buf)))
        { 
            tty_printf("\n!!! echec fb_write au cycle : %d !!!\n", proctime()); 
            exit();
        }
        fb_completed();
        tty_printf("- image affichee au cycle = %d \n",proctime());

        base  = base + nblocks;
        image = image + 1;

        tty_getc_irq(&byte);
	if (base == 640) base =0;

    } // end while

    exit();
} // end main
Example #17
0
/*
 *	Raster - rasterize stroke.
 *
 *  If immediate mode, draw the individual pixel on the frame buffer.
 *  If banded buffered mode, draw the portion in this band.  If it
 *     overflows into next band, requeue; else free the descriptor.
 *
 *  Method:
 *	Modified Bresenham algorithm.  Guaranteed to mark a dot for
 *	a zero-length stroke.  Please do not try to "improve" this code
 *	as it is extremely hard to get all aspects just right.
 */
static void
Raster(register stroke *vp, register struct band *np)
    /* -> rasterization descr */
    /* *np -> next band 1st descr */
{
    register short	dy;		/* raster within active band */

    CK_STROKE(vp);

    /*
     *  Draw the portion within this band.
     */
    for ( dy = vp->pixel.y - ystart; dy < lines_per_band; ) {

	/* set the appropriate pixel in the buffer */
	if ( immediate )  {
	    fb_write( fbp, vp->pixel.x, dy, vp->col, 1 );
	}  else  {
	    register unsigned char *pp;

	    pp = (unsigned char *)&buffer[((dy*Npixels) + vp->pixel.x)*sizeof(RGBpixel)];
	    COPYRGB( pp, vp->col );
	}

	if ( vp->major-- == 0 ) {
	    /* done! */
	    FREE_STROKE( vp );	/* return to "malloc" */
	    return;
	}

	if ( vp->e < 0 ) {
	    /* advance major & minor */
	    dy += vp->ysign;
	    vp->pixel.x += vp->xsign;
	    vp->e += vp->de;
	} else {
	    /* advance major only */
	    if ( vp->ymajor )	/* Y is major dir */
		++dy;
	    else			/* X is major dir */
		vp->pixel.x += vp->xsign;
	    vp->e -= vp->minor;
	}
    }

    /* overflow into next band; re-queue */
    vp->pixel.y = ystart + lines_per_band;
    Requeue( np, vp );       /* DDA parameters already set */
}
Example #18
0
/*
 * A routine to simulate the effect of fb_writerect() when a
 * particular display does not handle it.
 *
 * Returns number of pixels actually written.
 * Clipping to the screen may reduce the total if caller was sloppy.
 */
int
fb_sim_writerect(FBIO *ifp, int xmin, int ymin, int width, int height, const unsigned char *pp)
{
    register int y;
    register int tot;
    int got;
    size_t xlen;

    xlen = width;
    if (xmin + width > fb_getwidth(ifp))
	xlen = fb_getwidth(ifp) - xmin;

    tot = 0;
    for (y=ymin; y < ymin+height; y++) {
	got = fb_write(ifp, xmin, y, pp, xlen);
	tot += got;
	if (got != (int)xlen) break;
	pp += width * sizeof(RGBpixel);
    }
    return tot;
}
Example #19
0
HIDDEN ssize_t
mem_write(FBIO *ifp, int x, int y, const unsigned char *pixelp, size_t count)
{
    size_t pixels_to_end;

    if (x < 0 || x >= ifp->if_width || y < 0 || y >= ifp->if_height)
	return -1;

    /* make sure we don't run off the end of the buffer */
    pixels_to_end = ifp->if_width*ifp->if_height - (y*ifp->if_width + x);
    if (pixels_to_end < count)
	count = pixels_to_end;

    memcpy(&(MI(ifp)->mem[(y*ifp->if_width + x)*3]), (char *)pixelp, count*3);

    if (MI(ifp)->write_thru) {
	return fb_write(MI(ifp)->fbp, x, y, pixelp, count);
    } else {
	MI(ifp)->mem_dirty = 1;
    }
    return count;
}
Example #20
0
void
paintSpallFb(struct application *ap)
{
    unsigned char pixel[3];
    int x, y;
    int err;
    fastf_t celldist;
#if DEBUG_SPALLFB
    brst_log("paintSpallFb: a_x=%d a_y=%d a_cumlen=%g cellsz=%g zoom=%d\n",
	     ap->a_x, ap->a_y, ap->a_cumlen, cellsz, zoom);
#endif
    pixel[RED] = ap->a_color[RED] * 255;
    pixel[GRN] = ap->a_color[GRN] * 255;
    pixel[BLU] = ap->a_color[BLU] * 255;
    gridToFb(ap->a_x, ap->a_y, &x, &y);
    CenterCell(x);	/* center of cell */
    CenterCell(y);
    celldist = ap->a_cumlen/cellsz * zoom;
    x = roundToInt(x + VDOT(ap->a_ray.r_dir, gridhor) * celldist);
    y = roundToInt(y + VDOT(ap->a_ray.r_dir, gridver) * celldist);
    bu_semaphore_acquire(RT_SEM_STATS);
    err = fb_write(fbiop, x, y, pixel, 1);
    bu_semaphore_release(RT_SEM_STATS);
#if DEBUG_SPALLFB
    brst_log("paintSpallFb:gridhor=<%g, %g, %g> gridver=<%g, %g, %g>\n",
	     gridhor[X], gridhor[Y], gridhor[Z],
	     gridver[X], gridver[Y], gridver[Z]);
    brst_log("paintSpallFb:fb_write(x=%d, y=%d, pixel={%d, %d, %d})\n",
	     x, y,
	     (int) pixel[RED],
	     (int) pixel[GRN],
	     (int) pixel[BLU]
	);
#endif
    if (err == -1)
	brst_log("Write failed to pixel <%d, %d> from cell <%d, %d>.\n",
		 x, y, ap->a_x, ap->a_y);
    return;
}
Example #21
0
int
fb_sim_bwwriterect(FBIO *ifp, int xmin, int ymin, int width, int height, const unsigned char *pp)
{
    register int y;
    register int tot;
    int got;
    size_t xlen;
    unsigned char buf[SIMBUF_SIZE];

    if (width > SIMBUF_SIZE) {
	fb_log("fb_sim_bwwriterect() width of %d exceeds internal buffer, aborting\n", width);
	return -SIMBUF_SIZE;	/* FAIL */
    }

    xlen = width;
    if (xmin + width > fb_getwidth(ifp))
	xlen = fb_getwidth(ifp) - xmin;

    tot = 0;
    for (y=ymin; y < ymin+height; y++) {
	register int x;
	register unsigned char *bp;

	/* Copy monochrome (b&w) intensity into all three chans */
	bp = buf;
	for (x=0; x < width; x++) {
	    register unsigned char c = *pp++;
	    bp[0] = c;
	    bp[1] = c;
	    bp[2] = c;
	    bp += 3;
	}

	got = fb_write(ifp, xmin, y, buf, xlen);
	tot += got;
	if (got != (int)xlen) break;
    }
    return tot;
}
Example #22
0
int
_fb_pgout(register FBIO *ifp)
{
    int	scans, first_scan;

    /*fb_log( "_fb_pgout(%d)\n", ifp->if_pno );*/

    if ( ifp->if_pno < 0 )	/* Already paged out, return 1.	*/
	return	1;

    first_scan = ifp->if_pno * PAGE_SCANS;
    if ( first_scan + PAGE_SCANS > ifp->if_height )
	scans = ifp->if_height - first_scan;
    else
	scans = PAGE_SCANS;

    return	fb_write(	ifp,
				0,
				first_scan,
				ifp->if_pbase,
				scans * ifp->if_width
	);
}
Example #23
0
/*
 *
 * Usage:
 *	  procname cell xmin ymin width height color
 */
HIDDEN int
fbo_rect_tcl(ClientData clientData, Tcl_Interp *interp, int argc, char **argv)
{
    struct fb_obj *fbop = (struct fb_obj *)clientData;
    struct bu_vls vls;
    int xmin, ymin;
    int xmax, ymax;
    int width;
    int height;
    int i;
    RGBpixel pixel;

    if (argc != 7) {
	bu_vls_init(&vls);
	bu_vls_printf(&vls, "helplib fb_rect");
	Tcl_Eval(interp, bu_vls_addr(&vls));
	bu_vls_free(&vls);
	return TCL_ERROR;
    }

    if (sscanf(argv[2], "%d", &xmin) != 1) {
	Tcl_AppendResult(interp, "fb_rect: bad xmin value - ",
			 argv[2], (char *)NULL);
	return TCL_ERROR;
    }

    if (sscanf(argv[3], "%d", &ymin) != 1) {
	Tcl_AppendResult(interp, "fb_rect: bad ymin value - ",
			 argv[3], (char *)NULL);
	return TCL_ERROR;
    }

    /*  check coordinates */
    if (!fbo_coords_ok(interp, fbop->fbo_fbs.fbs_fbp, xmin, ymin)) {
	Tcl_AppendResult(interp,
			 "fb_rect: coordinates (", argv[2], ", ", argv[3],
			 ") are invalid.", (char *)NULL);
	return TCL_ERROR;
    }

    if (sscanf(argv[4], "%d", &width) != 1) {
	Tcl_AppendResult(interp, "fb_rect: bad width - ",
			 argv[4], (char *)NULL);
	return TCL_ERROR;
    }

    if (sscanf(argv[5], "%d", &height) != 1) {
	Tcl_AppendResult(interp, "fb_rect: bad height - ",
			 argv[5], (char *)NULL);
	return TCL_ERROR;
    }


    /* check width and height */
    if (width <=0  || height <=0) {
	Tcl_AppendResult(interp, "fb_rect: width and height must be > 0", (char *)NULL);
	return TCL_ERROR;
    }

    /*
     * Decompose the color list into its constituents.
     * For now must be in the form of rrr ggg bbb.
     */
    if (fbo_tcllist2color(interp, argv[6], pixel) == TCL_ERROR) {
	Tcl_AppendResult(interp, "fb_rect: invalid color spec: ", argv[6], ".",
			 (char *)NULL);
	return TCL_ERROR;
    }

    xmax = xmin + width;
    ymax = ymin + height;

    /* draw horizontal lines */
    for (i = xmin; i <= xmax; ++i) {
	/* working on bottom line */
	fb_write(fbop->fbo_fbs.fbs_fbp, i, ymin, pixel, 1);

	/* working on top line */
	fb_write(fbop->fbo_fbs.fbs_fbp, i, ymax, pixel, 1);
    }

    /* draw vertical lines */
    for (i = ymin; i <= ymax; ++i) {
	/* working on left line */
	fb_write(fbop->fbo_fbs.fbs_fbp, xmin, i, pixel, 1);

	/* working on right line */
	fb_write(fbop->fbo_fbs.fbs_fbp, xmax, i, pixel, 1);
    }

    return TCL_OK;
}
Example #24
0
/*
 * Set/get the pixel value at position (x, y).
 *
 * Usage:
 *	  procname pixel x y [rgb]
 */
HIDDEN int
fbo_pixel_tcl(ClientData clientData, Tcl_Interp *interp, int argc, char **argv)
{
    struct fb_obj *fbop = (struct fb_obj *)clientData;
    struct bu_vls vls;
    int x, y; 	/* pixel position */
    RGBpixel pixel;


    if (argc < 4)
	goto error;

    /* get pixel position */
    if (sscanf(argv[2], "%d", &x) != 1) {
	Tcl_AppendResult(interp, "fb_pixel: bad x value - ",
			 argv[2], (char *)NULL);
	return TCL_ERROR;
    }

    if (sscanf(argv[3], "%d", &y) != 1) {
	Tcl_AppendResult(interp, "fb_pixel: bad y value - ",
			 argv[3], (char *)NULL);
	return TCL_ERROR;
    }

    /* check pixel position */
    if (!fbo_coords_ok(interp, fbop->fbo_fbs.fbs_fbp, x, y)) {
	Tcl_AppendResult(interp,
			 "fb_pixel: coordinates (", argv[2], ", ", argv[3],
			 ") are invalid.", (char *)NULL);
	return TCL_ERROR;
    }

    /* get pixel value */
    if (argc == 4) {
	fb_rpixel(fbop->fbo_fbs.fbs_fbp, pixel);
	bu_vls_init(&vls);
	bu_vls_printf(&vls, "%d %d %d", pixel[RED], pixel[GRN], pixel[BLU]);
	Tcl_AppendResult(interp, bu_vls_addr(&vls), (char *)NULL);
	bu_vls_free(&vls);

	return TCL_OK;
    }

    /* set pixel value */
    if (argc == 5) {
	/*
	 * Decompose the color list into its constituents.
	 * For now must be in the form of rrr ggg bbb.
	 */

	if (fbo_tcllist2color(interp, argv[4], pixel) == TCL_ERROR) {
	    Tcl_AppendResult(interp, "fb_pixel: invalid color spec - ", argv[4], ".",
			     (char *)NULL);
	    return TCL_ERROR;
	}

	fb_write(fbop->fbo_fbs.fbs_fbp, x, y, pixel, 1);

	return TCL_OK;
    }

 error:
    bu_vls_init(&vls);
    bu_vls_printf(&vls, "helplib fb_pixel");
    Tcl_Eval(interp, bu_vls_addr(&vls));
    bu_vls_free(&vls);
    return TCL_ERROR;
}
static bool_t
display_Cells(long int ncells)
{
    Cell *gp, *ep = &grid[ncells];
    static int zoom;
    unsigned char *buf;
    static RGBpixel pixel;
    double lasty = -INFINITY;
    double dx, dy;
    int y_0 = 0, y_1;

    if (compute_fb_height) {
	dy = ((ymax - ymin) / cell_size + 1.0) * (hgt + grid_flag);
	if (compute_fb_height == SNUG_FIT)
	    fb_height = dy + (key_flag * 2 * hgt) + yorigin;
	else if (dy > LORES)	/* LOOSE_FIT */
	    fb_height = HIRES;
	else
	    fb_height = LORES;
    }
    if (compute_fb_width) {
	dx = ((xmax - xmin) / cell_size + 1.0) * (wid + grid_flag);
	if (compute_fb_width == SNUG_FIT)
	    fb_width = dx + xorigin;
	else if (dx > LORES)	/* LOOSE_FIT */
	    fb_width = HIRES;
	else
	    fb_width = LORES;
    }

    zoom = 1;
    fbiop = fb_open((fbfile[0] != '\0') ? fbfile : NULL, fb_width, fb_height);
    if (fbiop == FB_NULL)
	return 0;
    if (compute_fb_height || compute_fb_width) {
	bu_log("fb_size requested: %d %d\n", fb_width, fb_height);
	fb_width = fb_getwidth(fbiop);
	fb_height = fb_getheight(fbiop);
	bu_log("fb_size obtained: %d %d\n", fb_width, fb_height);
    }
    if (fb_wmap(fbiop, COLORMAP_NULL) == -1)
	bu_log("Cannot initialize color map\n");
    if (fb_zoom(fbiop, zoom, zoom) == -1)
	bu_log("Cannot set zoom <%d, %d>\n", zoom, zoom);
    if (erase_flag && fb_clear(fbiop, BACKGROUND) == -1)
	bu_log("Cannot clear frame buffer\n");

    buf = (unsigned char *) bu_malloc(sizeof(RGBpixel) * fb_width,
				      "line of frame buffer");
    if (debug_flag & CFB_DBG_MEM)
	bu_log("buf = %p... %d pixels @ %lu bytes/pixel\n",
	       (void *)buf, fb_width, sizeof(RGBpixel));

    for (gp = grid; gp < ep; gp++) {
	int x0, x1;

	/* Whenever Y changes, write out row of cells. */
	if (!ZERO(lasty - gp->c_y)) {
	    /* If first time, nothing to write out. */
	    if (!ZERO(lasty - INFINITY)) {
		if (debug_flag & CFB_DBG_GRID)
		    bu_log("%g = V2SCRY(%g)\n", V2SCRY(lasty), lasty);
		y_0 = V2SCRY(lasty);
		if (y_0 >= 0 && y_0 < fb_height) {
		    for (y_1 = y_0 + hgt; y_0 < y_1; y_0++)
			if (fb_write(fbiop, 0, y_0, buf, fb_width) == -1) {
			    bu_log("Couldn't write to <%d, %d>\n", 0, y_0);
			    (void) fb_close(fbiop);
			    return 0;
			}
		}
	    }
	    /* Clear buffer. */
	    for (x0 = 0; x0 < fb_width; x0++) {
		COPYRGB(&buf[3*x0], BACKGROUND);
	    }

	    /* Draw grid line between rows of cells. */
	    if (grid_flag && !ZERO(lasty - INFINITY)) {
		if (fb_write(fbiop, 0, y_0, buf, fb_width) == -1) {
		    bu_log("Couldn't write to <%d, %d>\n", 0, y_0);
		    (void) fb_close(fbiop);
		    return 0;
		}
		if (debug_flag & CFB_DBG_GRID)
		    bu_log("Writing grid row at %d\n", y_0);
	    }
	    lasty = gp->c_y;
	}
	val_To_RGB(gp->c_val, pixel);
	/* Be careful only to write color within bounds of the screen */
	x0 = H2SCRX(gp->c_x);
	if (x0 >= 0 && x0 <= fb_width - wid) {
	    for (x1 = x0 + wid; x0 < x1;  x0++) {
		COPYRGB(&buf[3*x0], pixel);
	    }
	}
    }

    /* Write out last row of cells. */
    if (debug_flag & CFB_DBG_GRID)
	bu_log("%g = V2SCRY(%g)\n", V2SCRY(lasty), lasty);
    for (y_0 = V2SCRY(lasty), y_1 = y_0 + hgt; y_0 < y_1;  y_0++)
	if (fb_write(fbiop, 0, y_0, buf, fb_width) == -1) {
	    bu_log("Couldn't write to <%d, %d>\n", 0, y_0);
	    (void) fb_close(fbiop);
	    return 0;
	}
    /* Draw color key. */
    if (key_flag && (fb_width < (10 + 1) * wid))
	bu_log("Width of key (%d) would exceed frame-buffer width (%d)\n",
	       (10 + 1) * wid, fb_width);
    else if (key_flag) {
	int i, j;
	double base;
	int scr_min, scr_max;
	int scr_center;	/* screen coord of center of view */
	int center_cell;	/* cell # of center of view */

	/* Clear buffer. */
	for (i = 0; i < fb_width; i++) {
	    COPYRGB(&buf[3*i], BACKGROUND);
	}
	/* Center the color key from side-to-side in the viewport.
	 * Find screen coords of min and max vals, clip to (0, fb_width).
	 * If there are fewer than 11 cells, the run the key
	 * from the left edge to beyond the right edge.
	 */
	scr_min = H2SCRX(xmin);
	scr_max = H2SCRX(xmax);
	CLAMP(scr_min, 0, fb_width);
	CLAMP(scr_max, 0, fb_width);

	scr_center = (scr_max + scr_min)/2;
	if ((center_cell = VPX2CX(SCRX2VPX(scr_center))) < 5)
	    center_cell = 5;

	/* Draw 10 cells for the color key */
	dom_cvt = 10.0;
	for (i = 0; i <= 10; i++) {
	    cell_val cv;

	    /*
	     * Determine where to start the key,
	     * being careful not to back up beyond the beginning of buf.
	     */
	    base = VPX2SCRX(CX2VPX(center_cell - 10/2 + i));

	    cv.v_scalar = i / 10.0;

	    val_To_RGB(cv, pixel);
	    for (j = 0; j < wid; j++) {
		int idx = base + j;
		COPYRGB(&buf[3*idx], pixel);
	    }
	}
	dom_cvt = 10.0 / (dom_max - dom_min);

	for (i = yorigin; i < yorigin+hgt; i++)
	    if (fb_write(fbiop, 0, i, buf, fb_width) == -1) {
		bu_log("Couldn't write to <%d, %d>\n", 0, i);
		(void) fb_close(fbiop);
		return 0;
	    }
    }
    (void) fb_close(fbiop);

    bu_free((char *) buf, "line of frame buffer");
    if (debug_flag & CFB_DBG_MEM)
	bu_log("freed buf, which is now %p\n", (void *)buf);
    return 1;
}
Example #26
0
/**
 * action performed at the end of each scanline
 */
void
view_eol(struct application *ap)
{
    int cpu = ap->a_resource->re_cpu;
    int i;

    if (overlay) {
	/*
	 * Overlay mode. Check if the pixel is an edge.  If so, write
	 * it to the framebuffer.
	 */
	for (i = 0; i < per_processor_chunk; ++i) {
	    if (writeable[cpu][i]) {
		/*
		 * Write this pixel
		 */
		bu_semaphore_acquire(BU_SEM_SYSCALL);
		fb_write(fbp, i, ap->a_y, &scanline[cpu][i*3], 1);
		bu_semaphore_release(BU_SEM_SYSCALL);
	    }
	}
	return;
    } else if (blend) {
	/*
	 * Blend mode.
	 *
	 * Read a line from the existing framebuffer, convert to HSV,
	 * manipulate, and put the results in the scanline as RGB.
	 */
	int replace_down = 0; /* flag that specifies if the pixel in the
			       * scanline below must be replaced.
			       */
	RGBpixel rgb;
	fastf_t hsv[3];

	bu_semaphore_acquire(BU_SEM_SYSCALL);
	if (fb_read(fbp, 0, ap->a_y, blendline[cpu], per_processor_chunk) < 0)
	    bu_exit(EXIT_FAILURE, "rtedge: error reading from framebuffer.\n");
	bu_semaphore_release(BU_SEM_SYSCALL);

	for (i = 0; i < per_processor_chunk; ++i) {
	    /*
	     * Is this pixel an edge?
	     */
	    if (writeable[cpu][i]) {

		/*
		 * The pixel is an edge, retrieve the appropriate
		 * pixel from the line buffer and convert it to HSV.
		 */
		rgb[RED] = blendline[cpu][i*3+RED];
		rgb[GRN] = blendline[cpu][i*3+GRN];
		rgb[BLU] = blendline[cpu][i*3+BLU];

		/*
		 * Is the pixel in the blendline array the background
		 * color? If so, look left and down to determine which
		 * pixel is the "source" of the edge. Unless, of
		 * course, we are on the bottom scanline or the
		 * leftmost column (x=y=0)
		 */
		if (i != 0 && ap->a_y != 0 && !diffpixel(rgb, fb_bg_color)) {
		    RGBpixel left;
		    RGBpixel down;

		    left[RED] = blendline[cpu][(i-1)*3+RED];
		    left[GRN] = blendline[cpu][(i-1)*3+GRN];
		    left[BLU] = blendline[cpu][(i-1)*3+BLU];

		    bu_semaphore_acquire(BU_SEM_SYSCALL);
		    fb_read(fbp, i, ap->a_y - 1, down, 1);
		    bu_semaphore_release(BU_SEM_SYSCALL);

		    if (diffpixel(left, fb_bg_color)) {
			/*
			 * Use this one.
			 */
			rgb[RED] = left[RED];
			rgb[GRN] = left[GRN];
			rgb[BLU] = left[BLU];
		    } else if (diffpixel(down, fb_bg_color)) {
			/*
			 * Use the pixel from the scanline below
			 */
			replace_down = 1;

			rgb[RED] = down[RED];
			rgb[GRN] = down[GRN];
			rgb[BLU] = down[BLU];
		    }
		}
		/*
		 * Convert to HSV
		 */
		bu_rgb_to_hsv(rgb, hsv);

		/*
		 * Now perform the manipulations.
		 */
		hsv[VAL] *= 3.0;
		hsv[SAT] /= 3.0;

		if (hsv[VAL] > 1.0) {
		    fastf_t d = hsv[VAL] - 1.0;

		    hsv[VAL] = 1.0;
		    hsv[SAT] -= d;
		    hsv[SAT] = hsv[SAT] >= 0.0 ? hsv[SAT] : 0.0;
		}

		/*
		 * Convert back to RGB.
		 */
		bu_hsv_to_rgb(hsv, rgb);

		if (replace_down) {
		    /*
		     * Write this pixel immediately, do not put it
		     * into the blendline since it corresponds to the
		     * wrong scanline.
		     */
		    bu_semaphore_acquire(BU_SEM_SYSCALL);
		    fb_write(fbp, i, ap->a_y, rgb, 1);
		    bu_semaphore_release(BU_SEM_SYSCALL);

		    replace_down = 0;
		} else {
		    /*
		     * Put this pixel back into the blendline array.
		     * We'll push it to the buffer when the entire
		     * scanline has been processed.
		     */
		    blendline[cpu][i*3+RED] = rgb[RED];
		    blendline[cpu][i*3+GRN] = rgb[GRN];
		    blendline[cpu][i*3+BLU] = rgb[BLU];
		}
	    } /* end "if this pixel is an edge" */
	} /* end pixel loop */

	/*
	 * Write the blendline to the framebuffer.
	 */
	bu_semaphore_acquire(BU_SEM_SYSCALL);
	fb_write(fbp, 0, ap->a_y, blendline[cpu], per_processor_chunk);
	bu_semaphore_release(BU_SEM_SYSCALL);
	return;
    } /* end blend */

    if (fbp != FBIO_NULL) {
	/*
	 * Simple whole scanline write to a framebuffer.
	 */
	bu_semaphore_acquire(BU_SEM_SYSCALL);
	fb_write(fbp, 0, ap->a_y, scanline[cpu], per_processor_chunk);
	bu_semaphore_release(BU_SEM_SYSCALL);
    }
    if (outputfile != NULL) {
	/*
	 * Write to a file.
	 */
	bu_semaphore_acquire(BU_SEM_SYSCALL);
	/* TODO : Add double type data to maintain resolution */
	icv_writeline(bif, ap->a_y, scanline[cpu],  ICV_DATA_UCHAR);
	bu_semaphore_release(BU_SEM_SYSCALL);
    }
    if (fbp == FBIO_NULL && outputfile == NULL)
	bu_log("rtedge: strange, no end of line actions taken.\n");

    return;

}
Example #27
0
HIDDEN void
do_Char(int c, int xpos, int ypos, int odd)
{
    register int    i, j;
    int base;
    int     	totwid = font.width;
    int     	down;
    static float	resbuf[FONTBUFSZ];
    static RGBpixel fbline[FONTBUFSZ];
#if DEBUG_STRINGS
    fb_log( "do_Char: c='%c' xpos=%d ypos=%d odd=%d\n",
	    c, xpos, ypos, odd );
#endif

    /* read in character bit map, with two blank lines on each end */
    for (i = 0; i < 2; i++)
	clear_buf (totwid, filterbuf[i]);
    for (i = font.height + 1; i >= 2; i--)
	fill_buf (font.width, filterbuf[i]);
    for (i = font.height + 2; i < font.height + 4; i++)
	clear_buf (totwid, filterbuf[i]);

    (void)SignedChar( font.dir[c].up );
    down = SignedChar( font.dir[c].down );

    /* Initial base line for filtering depends on odd flag. */
    base = (odd ? 1 : 2);


    /* Produce a RGBpixel buffer from a description of the character and
       the read back data from the frame buffer for anti-aliasing.
    */
    for (i = font.height + base; i >= base; i--)
    {
	squash(	filterbuf[i - 1],	/* filter info */
		filterbuf[i],
		filterbuf[i + 1],
		resbuf,
		totwid + 4
	    );
	fb_read( fbp, xpos, ypos - down + i, (unsigned char *)fbline, totwid+3);
	for (j = 0; j < (totwid + 3) - 1; j++)
	{
	    register int tmp;
	    /* EDITOR'S NOTE : do not rearrange this code,
	       the SUN compiler can't handle more
	       complex expressions. */
	    tmp = fbline[j][RED] & 0377;
	    fbline[j][RED] =
		(int)(paint[RED]*resbuf[j]+(1-resbuf[j])*tmp);
	    fbline[j][RED] &= 0377;
	    tmp = fbline[j][GRN] & 0377;
	    fbline[j][GRN] =
		(int)(paint[GRN]*resbuf[j]+(1-resbuf[j])*tmp);
	    fbline[j][GRN] &= 0377;
	    tmp = fbline[j][BLU] & 0377;
	    fbline[j][BLU] =
		(int)(paint[BLU]*resbuf[j]+(1-resbuf[j])*tmp);
	    fbline[j][BLU] &= 0377;
	}
	fb_write( fbp, xpos, ypos - down + i, (unsigned char *)fbline,  totwid+3 );
    }
    return;
}
Example #28
0
void
do_char(struct vfont *vfp, struct vfont_dispatch *vdp, int x, int y)
{
    int i, j;
    int base;
    int totwid = width;
    int ln;
    static float resbuf[FONTBUFSZ];
    static RGBpixel fbline[FONTBUFSZ];
    int bytes_wide;	/* # bytes/row in bitmap */

    bytes_wide = (width+7)>>3;

    /* Read in the character bit map, with two blank lines on each end. */
    for (i = 0; i < 2; i++)
        memset((char *)&filterbuf[i][0], 0, (totwid+4)*sizeof(int));

    for (ln=0, i = height + 1; i >= 2; i--, ln++)
        fill_buf (width, &filterbuf[i][0],
                  &vfp->vf_bits[vdp->vd_addr + bytes_wide*ln]);

    for (i = height + 2; i < height + 4; i++)
        memset((char *)&filterbuf[i][0], 0, (totwid+4)*sizeof(int));

    /* Initial base line for filtering depends on odd flag. */
    if (vdp->vd_down % 2)
        base = 1;
    else
        base = 2;

    /* Produce a RGBpixel buffer from a description of the character
     * and the read back data from the frame buffer for anti-aliasing.
     */
    for (i = height + base; i >= base; i--) {
        squash(filterbuf[i - 1],	/* filter info */
               filterbuf[i],
               filterbuf[i + 1],
               resbuf,
               totwid + 4
              );
        fb_read(fbp, x, y - vdp->vd_down + i, (unsigned char *)fbline, totwid+3);
        for (j = 0; j < (totwid + 3) - 1; j++) {
            int tmp;
            /* EDITOR'S NOTE : do not rearrange this code, the SUN
             * compiler can't handle more complex expressions.
             */

            tmp = fbline[j][RED] & 0377;
            fbline[j][RED] =
                (int)(pixcolor[RED]*resbuf[j]+(1-resbuf[j])*tmp);
            fbline[j][RED] &= 0377;
            tmp = fbline[j][GRN] & 0377;
            fbline[j][GRN] =
                (int)(pixcolor[GRN]*resbuf[j]+(1-resbuf[j])*tmp);
            fbline[j][GRN] &= 0377;
            tmp = fbline[j][BLU] & 0377;
            fbline[j][BLU] =
                (int)(pixcolor[BLU]*resbuf[j]+(1-resbuf[j])*tmp);
            fbline[j][BLU] &= 0377;
        }
        if (fb_write(fbp, x, y-vdp->vd_down+i, (unsigned char *)fbline, totwid+3) < totwid+3) {
            fprintf(stderr, "fblabel: pixel write error\n");
            bu_exit(1, NULL);
        }
    }
}
Example #29
0
int
main(int argc, char **argv)
{
    FBIO *fbp;
    int i;
    int file_width;		/* unclipped width of rectangle */
    int file_skiplen;		/* # of pixels to skip on l.h.s. */
    int screen_xbase;		/* screen X of l.h.s. of rectangle */
    int screen_xlen;		/* clipped len of rectangle */
    int ncolors;

    infp = stdin;
    if (!get_args(argc, argv)) {
	(void)fputs(usage, stderr);
	bu_exit(1, NULL);
    }

    rle_dflt_hdr.rle_file = infp;
    if (rle_get_setup(&rle_dflt_hdr) < 0) {
	fprintf(stderr, "rle-fb: Error reading setup information\n");
	bu_exit(1, NULL);
    }

    if (r_debug) {
	fprintf(stderr, "Image bounds\n\tmin %d %d\n\tmax %d %d\n",
		rle_dflt_hdr.xmin, rle_dflt_hdr.ymin,
		rle_dflt_hdr.xmax, rle_dflt_hdr.ymax);
	fprintf(stderr, "%d color channels\n", rle_dflt_hdr.ncolors);
	fprintf(stderr, "%d color map channels\n", rle_dflt_hdr.ncmap);
	if (rle_dflt_hdr.alpha)
	    fprintf(stderr, "Alpha Channel present in input, ignored.\n");
	for (i=0; i < rle_dflt_hdr.ncolors; i++)
	    fprintf(stderr, "Background channel %d = %d\n",
		    i, rle_dflt_hdr.bg_color[i]);
	rle_debug(1);
    }

    if (rle_dflt_hdr.ncmap == 0)
	crunch = 0;

    /* Only interested in R, G, & B */
    RLE_CLR_BIT(rle_dflt_hdr, RLE_ALPHA);
    for (i = 3; i < rle_dflt_hdr.ncolors; i++)
	RLE_CLR_BIT(rle_dflt_hdr, i);
    ncolors = rle_dflt_hdr.ncolors > 3 ? 3 : rle_dflt_hdr.ncolors;

    /* Optional switch of library to overlay mode */
    if (overlay) {
	rle_dflt_hdr.background = 1;		/* overlay */
	override_background = 0;
    }

    /* Optional background color override */
    if (override_background) {
	for (i=0; i<ncolors; i++)
	    rle_dflt_hdr.bg_color[i] = background[i];
    }

    file_width = rle_dflt_hdr.xmax - rle_dflt_hdr.xmin + 1;

    /* If screen sizes not specified, try to display rectangle part > 0 */
    if (screen_width == 0) {
	screen_width = rle_dflt_hdr.xmax + 1;
	if (scr_xoff > 0)
	    screen_width += scr_xoff;
    }
    if (screen_height == 0) {
	screen_height = rle_dflt_hdr.ymax + 1;
	if (scr_yoff > 0)
	    screen_height += scr_yoff;
    }

    /* Incorporate command-line rectangle repositioning */
    rle_dflt_hdr.xmin += scr_xoff;
    rle_dflt_hdr.xmax += scr_xoff;
    rle_dflt_hdr.ymin += scr_yoff;

    /* Pretend saved image origin is at 0, clip & position in fb_write call */
    screen_xbase = rle_dflt_hdr.xmin;
    rle_dflt_hdr.xmax -= screen_xbase;
    rle_dflt_hdr.xmin = 0;

    if ((fbp = fb_open(framebuffer, screen_width, screen_height)) == FBIO_NULL)
	bu_exit(12, NULL);

    /* Honor original screen size desires, if set, unless they shrank */
    if (screen_width > 0 && fb_getwidth(fbp) < screen_width)
	screen_width = fb_getwidth(fbp);
    if (screen_height > 0 && fb_getheight(fbp) < screen_height)
	screen_height = fb_getheight(fbp);

    /* Discard any scanlines which exceed screen height */
    if (rle_dflt_hdr.ymax > screen_height-1)
	rle_dflt_hdr.ymax = screen_height-1;

    /* Clip left edge */
    screen_xlen = rle_dflt_hdr.xmax + 1;
    file_skiplen = 0;
    if (screen_xbase < 0) {
	file_skiplen = -screen_xbase;
	screen_xbase = 0;
	screen_xlen -= file_skiplen;
    }
    /* Clip right edge */
    if (screen_xbase + screen_xlen > screen_width)
	screen_xlen = screen_width - screen_xbase;
    if (screen_xlen <= 0 ||
	rle_dflt_hdr.ymin > screen_height ||
	rle_dflt_hdr.ymax < 0) {
	fprintf(stderr,
		"rle-fb:  Warning:  RLE image rectangle entirely off screen\n");
	goto done;
    }

    scan_buf = (unsigned char *)malloc(sizeof(RGBpixel) * screen_width);

    for (i=0; i < ncolors; i++)
	rows[i] = (unsigned char *)malloc((size_t)file_width);
    for (; i < 3; i++)
	rows[i] = rows[0];	/* handle monochrome images */

    /*
     * Import Utah color map, converting to libfb format.
     * Check for old format color maps, where high 8 bits
     * were zero, and correct them.
     * XXX need to handle < 3 channels of color map, by replication.
     */
    if (rle_dflt_hdr.ncmap > 0) {
	int maplen = (1 << rle_dflt_hdr.cmaplen);
	int all = 0;
	for (i=0; i<256; i++) {
	    cmap.cm_red[i] = rle_dflt_hdr.cmap[i];
	    cmap.cm_green[i] = rle_dflt_hdr.cmap[i+maplen];
	    cmap.cm_blue[i] = rle_dflt_hdr.cmap[i+2*maplen];
	    all |= cmap.cm_red[i] | cmap.cm_green[i] |
		cmap.cm_blue[i];
	}
	if ((all & 0xFF00) == 0 && (all & 0x00FF) != 0) {
	    /* This is an old (Edition 2) color map.
	     * Correct by shifting it left 8 bits.
	     */
	    for (i=0; i<256; i++) {
		cmap.cm_red[i] <<= 8;
		cmap.cm_green[i] <<= 8;
		cmap.cm_blue[i] <<= 8;
	    }
	    fprintf(stderr,
		    "rle-fb: correcting for old style colormap\n");
	}
    }
    if (rle_dflt_hdr.ncmap > 0 && !crunch)
	(void)fb_wmap(fbp, &cmap);
    else
	(void)fb_wmap(fbp, COLORMAP_NULL);

    /* Handle any lines below zero in y.  Decode and discard. */
    for (i = rle_dflt_hdr.ymin; i < 0; i++)
	rle_getrow(&rle_dflt_hdr, rows);

    for (; i <= rle_dflt_hdr.ymax; i++) {
	unsigned char *pp = (unsigned char *)scan_buf;
	rle_pixel *rp = &(rows[0][file_skiplen]);
	rle_pixel *gp = &(rows[1][file_skiplen]);
	rle_pixel *bp = &(rows[2][file_skiplen]);
	int j;

	if (overlay) {
	    fb_read(fbp, screen_xbase, i, scan_buf, screen_xlen);
	    for (j = 0; j < screen_xlen; j++) {
		*rp++ = *pp++;
		*gp++ = *pp++;
		*bp++ = *pp++;
	    }
	    pp = (unsigned char *)scan_buf;
	    rp = &(rows[0][file_skiplen]);
	    gp = &(rows[1][file_skiplen]);
	    bp = &(rows[2][file_skiplen]);
	}

	rle_getrow(&rle_dflt_hdr, rows);

	/* Grumble, convert from Utah layout */
	if (!crunch) {
	    for (j = 0; j < screen_xlen; j++) {
		*pp++ = *rp++;
		*pp++ = *gp++;
		*pp++ = *bp++;
	    }
	} else {
	    for (j = 0; j < screen_xlen; j++) {
		*pp++ = cmap.cm_red[*rp++]>>8;
		*pp++ = cmap.cm_green[*gp++]>>8;
		*pp++ = cmap.cm_blue[*bp++]>>8;
	    }
	}
	if (fb_write(fbp, screen_xbase, i, scan_buf, screen_xlen) != screen_xlen) break;
    }
done:
    fb_close(fbp);
    return 0;
}
Example #30
0
/*
 *
 * Usage:
 * procname cell xmin ymin width height color
 */
HIDDEN int
fbo_rect_tcl(void *clientData, int argc, const char **argv)
{
    struct fb_obj *fbop = (struct fb_obj *)clientData;
    int xmin, ymin;
    int xmax, ymax;
    int width;
    int height;
    int i;
    RGBpixel pixel;

    if (argc != 7) {
	bu_log("ERROR: expecting seven arguments\n");
	return BRLCAD_ERROR;
    }

    if (sscanf(argv[2], "%d", &xmin) != 1) {
	bu_log("fb_rect: bad xmin value - %s", argv[2]);
	return BRLCAD_ERROR;
    }

    if (sscanf(argv[3], "%d", &ymin) != 1) {
	bu_log("fb_rect: bad ymin value - %s", argv[3]);
	return BRLCAD_ERROR;
    }

    /* check coordinates */
    if (!fbo_coords_ok(fbop->fbo_fbs.fbs_fbp, xmin, ymin)) {
	bu_log("fb_rect: coordinates (%s, %s) are invalid.", argv[2], argv[3]);
	return BRLCAD_ERROR;
    }

    if (sscanf(argv[4], "%d", &width) != 1) {
	bu_log("fb_rect: bad width - %s", argv[4]);
	return BRLCAD_ERROR;
    }

    if (sscanf(argv[5], "%d", &height) != 1) {
	bu_log("fb_rect: bad height - %s", argv[5]);
	return BRLCAD_ERROR;
    }


    /* check width and height */
    if (width <=0  || height <=0) {
	bu_log("fb_rect: width and height must be > 0");
	return BRLCAD_ERROR;
    }

    /*
     * Decompose the color list into its constituents.
     * For now must be in the form of rrr ggg bbb.
     */
    if (fbo_tcllist2color(argv[6], pixel) == BRLCAD_ERROR) {
	bu_log("fb_rect: invalid color spec: %s", argv[6]);
	return BRLCAD_ERROR;
    }

    xmax = xmin + width;
    ymax = ymin + height;

    /* draw horizontal lines */
    for (i = xmin; i <= xmax; ++i) {
	/* working on bottom line */
	fb_write(fbop->fbo_fbs.fbs_fbp, i, ymin, pixel, 1);

	/* working on top line */
	fb_write(fbop->fbo_fbs.fbs_fbp, i, ymax, pixel, 1);
    }

    /* draw vertical lines */
    for (i = ymin; i <= ymax; ++i) {
	/* working on left line */
	fb_write(fbop->fbo_fbs.fbs_fbp, xmin, i, pixel, 1);

	/* working on right line */
	fb_write(fbop->fbo_fbs.fbs_fbp, xmax, i, pixel, 1);
    }

    return BRLCAD_OK;
}