Ejemplo n.º 1
0
bool SaveARGB(const char *fileName, BYTE *data, int width, int height)
{
    bool result = false;
    if (!data)
        return result;

    ARGBPixel *input = (ARGBPixel *)data;
    BitmapPixel *output = new BitmapPixel[BITMAP_SIZE(width, height)];
    memset(output, 0, BITMAP_SIZE(width, height) * sizeof(BitmapPixel));

    for(int row = 0; row < height; ++row)
    {
        for(int col = 0; col < width; ++col)
        {
            int outputIdx = BITMAP_INDEX(col, row, width);
            int inputIdx = ((height - row - 1) * width) + col;

            output[outputIdx].red = input[inputIdx].red;
            output[outputIdx].green = input[inputIdx].green;
            output[outputIdx].blue = input[inputIdx].blue;
        }
    }

    result = SaveBitmap(fileName, (BYTE *)output, width, height);

    delete [] output;

    return result;
}
Ejemplo n.º 2
0
static int _irqext_expand(void)
{
	unsigned int old_size = iectrl.count;
	unsigned int new_size = iectrl.count + HOST_IRQEXT_CHUNK;
	struct vmm_host_irq **irqs = NULL;
	unsigned long *bitmap = NULL;

	irqs = realloc(iectrl.irqs,
		       old_size * sizeof (struct vmm_host_irq *),
		       new_size * sizeof (struct vmm_host_irq *));
	if (!irqs) {
		vmm_printf("%s: Failed to reallocate extended IRQ array from "
			   "%d to %d bytes\n", __func__, old_size, new_size);
		return VMM_ENOMEM;
	}

	old_size = BITMAP_SIZE(old_size);
	new_size = BITMAP_SIZE(new_size);

	bitmap = realloc(iectrl.bitmap, old_size, new_size);
	if (!bitmap) {
		vmm_printf("%s: Failed to reallocate extended IRQ bitmap from "
			   "%d to %d bytes\n", __func__, old_size, new_size);
		vmm_free(irqs);
		return VMM_ENOMEM;
	}

	iectrl.irqs = irqs;
	iectrl.bitmap = bitmap;
	iectrl.count += HOST_IRQEXT_CHUNK;

	return VMM_OK;
}
Ejemplo n.º 3
0
bool SaveBGR(const char *fileName, BYTE *data, int width, int height)
{
    bool result = false;

    if (!data)
        return false;
    RGBPixel *input = (RGBPixel *)data;
    BitmapPixel *output = new BitmapPixel[BITMAP_SIZE(width, height)];

    // Pad bytes need to be set to zero, it's easier to just set the entire chunk of memory
    memset(output, 0, BITMAP_SIZE(width, height) * sizeof(BitmapPixel));

    for(int row = 0; row < height; ++row)
    {
        for(int col = 0; col < width; ++col)
        {
            // In a bitmap (0,0) is at the bottom left, in the frame buffer it is the top left.
            int outputIdx = BITMAP_INDEX(col, row, width);
            int inputIdx = ((height - row - 1) * width) + col;

            output[outputIdx].red = input[inputIdx].blue;
            output[outputIdx].green = input[inputIdx].green;
            output[outputIdx].blue = input[inputIdx].red;
        }
    }

    result = SaveBitmap(fileName, (BYTE *)output, width, height);

    delete [] output;

    return result;
}
Ejemplo n.º 4
0
STATIC_INLINE StgPtr
thread_arg_block (StgFunInfoTable *fun_info, StgClosure **args)
{
    StgPtr p;
    StgWord bitmap;
    nat size;

    p = (StgPtr)args;
    switch (fun_info->f.fun_type) {
    case ARG_GEN:
	bitmap = BITMAP_BITS(fun_info->f.b.bitmap);
	size = BITMAP_SIZE(fun_info->f.b.bitmap);
	goto small_bitmap;
    case ARG_GEN_BIG:
	size = GET_FUN_LARGE_BITMAP(fun_info)->size;
	thread_large_bitmap(p, GET_FUN_LARGE_BITMAP(fun_info), size);
	p += size;
	break;
    default:
	bitmap = BITMAP_BITS(stg_arg_bitmaps[fun_info->f.fun_type]);
	size = BITMAP_SIZE(stg_arg_bitmaps[fun_info->f.fun_type]);
    small_bitmap:
	while (size > 0) {
	    if ((bitmap & 1) == 0) {
		thread((StgClosure **)p);
	    }
	    p++;
	    bitmap = bitmap >> 1;
	    size--;
	}
	break;
    }
    return p;
}
Ejemplo n.º 5
0
bool SaveRGBPlanar(const char *fileName, BYTE *data, int width, int height)
{
    if (!data)
        return false;

    const char *nameExt[] = {"red", "green", "blue"};
    BitmapPixel *output = new BitmapPixel[BITMAP_SIZE(width, height)];
    memset(output, 0, BITMAP_SIZE(width, height) * sizeof(BitmapPixel));

    for(int color = 0; color < 3; ++color)
    {
        for(int row = 0; row < height; ++row)
        {
            for(int col = 0; col < width; ++col)
            {   
                int outputIdx = BITMAP_INDEX(col, row, width);
                int inputIdx = ((height - row - 1) * width) + col;

                output[outputIdx].blue = 0;
                output[outputIdx].green = 0;
                output[outputIdx].red = 0;

                switch(color)
                {
                case 0:
                    output[outputIdx].red = data[inputIdx];
                    break;

                case 1:
                    output[outputIdx].green = data[inputIdx + (width * height)];
                    break;

                case 2:
                    output[outputIdx].blue = data[inputIdx + 2 * (width * height)];
                    break;

                default:
                    break;
                }
            }
        }

        std::string outputFile = fileName;
        size_t find = outputFile.find_last_of(".");

        outputFile.insert(find, "-");
        outputFile.insert(find+1, nameExt[color]);

        if(!SaveBitmap(outputFile.c_str(), (BYTE *)output, width, height))
        {
            delete [] output;
            return false;
        }
    }

    delete [] output;

    return true;
}
Ejemplo n.º 6
0
/*
 ***************************************************************************
 * Determine if a stat header line has to be displayed.
 *
 * RETURNS:
 * TRUE if a header line has to be displayed.
 ***************************************************************************
*/
int check_line_hdr(void)
{
	int i, rc = FALSE;

	/* Get number of options entered on the command line */
	if (get_activity_nr(act, AO_SELECTED, COUNT_OUTPUTS) > 1)
		return TRUE;

	for (i = 0; i < NR_ACT; i++) {
		if (IS_SELECTED(act[i]->options)) {
			/* Special processing for activities using a bitmap */
			if (act[i]->bitmap) {
				if (count_bits(act[i]->bitmap->b_array,
					       BITMAP_SIZE(act[i]->bitmap->b_size)) > 1) {
					rc = TRUE;
				}
			}
			else if (act[i]->nr > 1) {
				rc = TRUE;
			}
			/* Stop now since we have only one selected activity */
			break;
		}
	}

	return rc;
}
Ejemplo n.º 7
0
an_icon *IconResourceToIcon(  FILE *fp, an_icon_file *icon_file, unsigned i )
{
    an_icon_resource    *res;
    BITMAPINFO          *bm;
    BITMAPINFOHEADER    *h;
    an_icon             *icon;

    if( i >= icon_file->count ) return( NULL );
    res = &icon_file->resources[ i ];
    fseek( fp, res->DIB_offset, SEEK_SET );
    bm = ReadIconBitmap( fp );
    if( bm ) {
        icon = UtilMalloc( sizeof( an_icon ) );
        icon->bm = bm;
        h = &bm->bmiHeader;
        // h->biHeight /= 2;            /* code gen bug */
        h->biHeight = res->height;      /* they have height * 2 in this field */
        h->biSizeImage =
            BITS_TO_BYTES( h->biWidth * h->biBitCount, h->biHeight );
        icon->xor_size = h->biSizeImage;
        icon->and_size = BITS_TO_BYTES( h->biWidth, h->biHeight );
        icon->xor_mask = UtilMalloc( icon->xor_size + icon->and_size );
        icon->and_mask = (char *)icon->xor_mask + icon->xor_size;
        fseek( fp, res->DIB_offset + BITMAP_SIZE( h ), SEEK_SET );
        fread( icon->xor_mask, icon->xor_size + icon->and_size, 1, fp );
        return( icon );
    }
    return( NULL );
} /* IconResourceToIcon */
Ejemplo n.º 8
0
static CodeSpaceArena *
alloc_arena(size_t aloclogsiz, CodeSpaceArena *prev_csa)
{
  uint64_t rbitmap;
  CodeSpaceArena *arena;
  int allocsiz;
  int bitmap_size;
  int allff_size;
  int rest_size;
  
  arena = raw_alloc_arena(CODE_SPACE_SIZE);
  arena->next_and_size = ((uintptr_t)prev_csa) | aloclogsiz;

  /* fill bitmap: 1 means free */
  allocsiz = 16 << aloclogsiz;
  bitmap_size = BITMAP_SIZE(allocsiz);
  allff_size = (bitmap_size / 64) * 8;
  memset(arena->bitmap, 0xff, allff_size);
  
  /* rest of bit */
  rest_size = bitmap_size - allff_size * 8;
  rbitmap = (1 << (rest_size)) - 1;
  //fprintf(stderr, "%x %x \n", csarena_allocarea_tab[aloclogsiz], bitmap_size);
  arena->bitmap[csarena_allocarea_tab[aloclogsiz] - 2] = rbitmap;
  /* gatekeeper bit */
  arena->bitmap[csarena_allocarea_tab[aloclogsiz] - 1] = 0xff;

  return arena;
}
Ejemplo n.º 9
0
struct page_allocator *page_allocator_init(char *start, size_t len, size_t page_size) {
	char *pages_start;
	struct page_allocator *allocator;
	unsigned int pages;
	size_t bitmap_len;

	if (len < page_size) {
		return NULL;
	}

	start = (char *) binalign_bound((uintptr_t) start, 16);
	pages = len / page_size;
	pages_start = (char *) binalign_bound((uintptr_t) start, page_size);

	bitmap_len = sizeof(unsigned long) * BITMAP_SIZE(pages + 1); /* one for guardbit */

	while (sizeof(struct page_allocator) + bitmap_len > pages_start - start) {
		pages_start += page_size;
		pages --;
		assert(pages > 0);
	}

	allocator = (struct page_allocator *) start;
	allocator->pages_start = pages_start;
	allocator->pages_n = pages;
	allocator->page_size = page_size;
	allocator->free = pages * page_size;
	allocator->bitmap_len = bitmap_len;
	allocator->bitmap = (unsigned long *)((uintptr_t)&allocator->bitmap + sizeof(allocator->bitmap));

	memset(allocator->bitmap, 0, bitmap_len);
	bitmap_set_bit(allocator->bitmap, pages);

	return allocator;
}
Ejemplo n.º 10
0
/*
 * Inicializa el Buddy Allocator
 *
 * Aca lo que hacemos es inicializar las listas de bloques libres
 * de tamano 2^n. Tambien le asignamos memoria a los bitmaps
 * que van a representar el estado de cada bloque de paginas.
 * Los bitmaps en realidad no son necesarios. En un futuro los voy
 * a sacar y voy a implementarlo de la forma que esta en el kernel
 * 2.6
 */
void
init_buddy(void)
{
        int i;
        buddy_list_t *freelist = buddy.free_lists;

        /*
         * No aseguramos que corremos en un sistema de al menos 2^MAX_ORDER
         * paginas. MAX_ORDER = 10 asi que el minimo de memoria seria 4Mbytes
         */
        assert(sys_info.sys_pages >= (1 << MAX_ORDER));

        size_t nbytes = 0;
        for (i = 0; i < MAX_ORDER; i++)
                nbytes += BITMAP_SIZE(sys_info.sys_pages, i);

        char *memory = (char *) bootmem_alloc(nbytes);
        if (!memory)
                panic("Error alocando bitmap para el buddy allocator");

        /* Inicializar los bitmap con los buddies */
        for (i = 0; i < MAX_ORDER; i++)
        {
                /* Inicializamos la lista en vacio */
                INIT_LIST_HEAD(&freelist->head);
                freelist->free_pages = 0;

                freelist->page_bitmap = (bitmap_t) memory;

                /*
                 * Las paginas en un principio las ponemos como todas en uso
                 * asi cuando llamamos a bootmem_retire liberamos solo
                 * las paginas que no estaban en uso y no tenemos que marcar
                 * puntualmente las que estaban siendo usadas.
                 */
                bitmap_zero(freelist->page_bitmap, sys_info.sys_pages);

                memory += BITMAP_SIZE(sys_info.sys_pages, i);

                freelist++;
        }

        return;
}
Ejemplo n.º 11
0
/*
 ***************************************************************************
 * Parse string containing a set of coma-separated values or ranges of
 * values (e.g. "0,2-5,10-"). The ALL keyword is allowed and indicate that
 * all possible values are selected.
 *
 * IN:
 * @strargv	Current argument in list to parse.
 * @bitmap	Bitmap whose contents will indicate which values have been
 *		selected.
 * @max_val	Upper limit that value should not reach.
 * @__K_VALUE0	Keyword corresponding to the first bit in bitmap (e.g "all",
 *		"SUM"...)
 *
 * OUT:
 * @bitmap	Bitmap updated with selected values.
 *
 * RETURNS:
 * 0 on success, 1 otherwise.
 ***************************************************************************
 */
int parse_values(char *strargv, unsigned char bitmap[], int max_val, const char *__K_VALUE0)
{
	int i, val_low, val;
	char *t, *s, *valstr, range[16];

	if (!strcmp(strargv, K_ALL)) {
		/* Set bit for every possible values (CPU, IRQ, etc.) */
		memset(bitmap, ~0, BITMAP_SIZE(max_val));
		return 0;
	}

	for (t = strtok(strargv, ","); t; t = strtok(NULL, ",")) {
		if (!strcmp(t, __K_VALUE0)) {
			/*
			 * Set bit 0 in bitmap. This may correspond
			 * to CPU "all" or IRQ "SUM" for example.
			 */
			bitmap[0] |= 1;
		}
		else {
			/* Parse value or range of values */
			strncpy(range, t, 16);
			range[15] = '\0';
			valstr = t;
			if ((s = index(range, '-')) != NULL) {
				/* Possible range of values */
				*s = '\0';
				if (parse_valstr(range, max_val, &val_low) || (val_low < 0))
					return 1;
				valstr = s + 1;
			}
			if (parse_valstr(valstr, max_val, &val))
				return 1;
			if (s && val < 0) {
				/* Range of values with no upper limit (e.g. "3-") */
				val = max_val - 1;
			}
			if ((!s && (val < 0)) || (s && (val < val_low)))
				/*
				 * Individual value: string cannot be empty.
				 * Range of values: n-m: m can be empty (e.g. "3-") but
				 * cannot be lower than n.
				 */
				return 1;
			if (!s) {
				val_low = val;
			}
			for (i = val_low; i <= val; i++) {
				bitmap[(i + 1) >> 3] |= 1 << ((i + 1) & 0x07);
			}
		}
	}

	return 0;
}
Ejemplo n.º 12
0
static BITMAPINFO *ReadIconBitmap( FILE *fp )
{
    BITMAPINFO          *bm;
    BITMAPINFOHEADER    *header;
    long                DIB_offset, bitmap_size;

    header = UtilMalloc( sizeof( BITMAPINFOHEADER ) );
    DIB_offset = ftell( fp );
    fread( header, sizeof( BITMAPINFOHEADER ), 1, fp );
    fseek( fp, DIB_offset, SEEK_SET );
    bitmap_size = BITMAP_SIZE( header );
    bm = realloc( header, bitmap_size );
    if( !bm ) return( NULL );
    fread( bm, bitmap_size, 1, fp );
    return( bm );
} /* ReadIconBitmap */
Ejemplo n.º 13
0
struct draw *
draw_new (int width, int height)
{
  struct draw *draw;
  
  draw = xmalloc (_ALIGN (sizeof (struct draw), 4));
  
  draw->width  = width;
  draw->height = height;
  draw->total_size = BITMAP_SIZE (width, height, 24);
  draw->pixels = xmalloc (draw->total_size + 4);
  
  printf ("Total size: %d\n", draw->total_size);
  
  memset (draw->pixels, 0, draw->total_size);
  
  return draw;
}
Ejemplo n.º 14
0
bool SaveBitmap(const char *fileName, BYTE *data, int width, int height)
{
    BITMAPFILEHEADER fileHeader;
    BITMAPINFOHEADER infoHeader;
    FILE *outputFile;
    bool bRet = false;

    if (data)
    {
        if(outputFile = fopen(fileName, "wb"))
        {
            width = (width + 3) & (~3);
            int size = width * height * 3; // 24 bits per pixel

            fileHeader.bfType = 0x4D42;
            fileHeader.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + size;
            fileHeader.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);

            infoHeader.biSize = sizeof(BITMAPINFOHEADER);
            infoHeader.biWidth = width;
            infoHeader.biHeight = height;
            infoHeader.biPlanes = 1;
            infoHeader.biBitCount = 24;
            infoHeader.biCompression = BI_RGB;
            infoHeader.biSizeImage = BITMAP_SIZE(width, height);
            infoHeader.biXPelsPerMeter = 0;
            infoHeader.biYPelsPerMeter = 0;
            infoHeader.biClrUsed = 0;
            infoHeader.biClrImportant = 0;

            fwrite((unsigned char *)&fileHeader, 1, sizeof(BITMAPFILEHEADER), outputFile);
            fwrite((unsigned char *)&infoHeader, 1, sizeof(BITMAPINFOHEADER), outputFile);
            fwrite(data, 1, size, outputFile);

            bRet = true;
            fclose(outputFile);
        }
    }

    return bRet;
}
Ejemplo n.º 15
0
/*
 ***************************************************************************
 * Read stats for current activity from file and display them.
 *
 * IN:
 * @ifd		Input file descriptor.
 * @fpos	Position in file where reading must start.
 * @curr	Index in array for current sample statistics.
 * @rows	Number of rows of screen.
 * @act_id	Activity to display.
 * @file_actlst	List of activities in file.
 * @file	Name of file being read.
 * @file_magic	file_magic structure filled with file magic header data.
 *
 * OUT:
 * @curr	Index in array for next sample statistics.
 * @cnt		Number of remaining lines of stats to write.
 * @eosaf	Set to TRUE if EOF (end of file) has been reached.
 * @reset	Set to TRUE if last_uptime variable should be
 * 		reinitialized (used in next_slice() function).
 ***************************************************************************
 */
void handle_curr_act_stats(int ifd, off_t fpos, int *curr, long *cnt, int *eosaf,
			   int rows, unsigned int act_id, int *reset,
			   struct file_activity *file_actlst, char *file,
			   struct file_magic *file_magic)
{
	int p;
	unsigned long lines = 0;
	unsigned char rtype;
	int davg = 0, next, inc = -2;

	if (lseek(ifd, fpos, SEEK_SET) < fpos) {
		perror("lseek");
		exit(2);
	}

	/*
	 * Restore the first stats collected.
	 * Used to compute the rate displayed on the first line.
	 */
	copy_structures(act, id_seq, record_hdr, !*curr, 2);

	*cnt  = count;

	/* Assess number of lines printed */
	if ((p = get_activity_position(act, act_id)) >= 0) {
		if (act[p]->bitmap) {
			inc = count_bits(act[p]->bitmap->b_array,
					 BITMAP_SIZE(act[p]->bitmap->b_size));
		}
		else {
			inc = act[p]->nr;
		}
	}
	if (inc < 0) {
		/* Should never happen */
		PANIC(inc);
	}

	do {
		/* Display count lines of stats */
		*eosaf = sa_fread(ifd, &record_hdr[*curr],
				  RECORD_HEADER_SIZE, SOFT_SIZE);
		rtype = record_hdr[*curr].record_type;

		if (!*eosaf && (rtype != R_RESTART) && (rtype != R_COMMENT)) {
			/* Read the extra fields since it's not a special record */
			read_file_stat_bunch(act, *curr, ifd, file_hdr.sa_act_nr, file_actlst);
		}

		if ((lines >= rows) || !lines) {
			lines = 0;
			dis = 1;
		}
		else
			dis = 0;

		if (!*eosaf && (rtype != R_RESTART)) {

			if (rtype == R_COMMENT) {
				/* Display comment */
				next = sar_print_special(*curr, tm_start.use, tm_end.use,
						     R_COMMENT, ifd, file, file_magic);
				if (next) {
					/* A line of comment was actually displayed */
					lines++;
				}
				continue;
			}

			/* next is set to 1 when we were close enough to desired interval */
			next = write_stats(*curr, USE_SA_FILE, cnt, tm_start.use, tm_end.use,
					   *reset, act_id);
			if (next && (*cnt > 0)) {
				(*cnt)--;
			}
			if (next) {
				davg++;
				*curr ^=1;
				lines += inc;
			}
			*reset = FALSE;
		}
	}
	while (*cnt && !*eosaf && (rtype != R_RESTART));

	if (davg) {
		write_stats_avg(!*curr, USE_SA_FILE, act_id);
	}

	*reset = TRUE;
}
Ejemplo n.º 16
0
void
printStackChunk( StgPtr sp, StgPtr spBottom )
{
    StgWord bitmap;
    const StgInfoTable *info;

    ASSERT(sp <= spBottom);
    for (; sp < spBottom; sp += stack_frame_sizeW((StgClosure *)sp)) {

	info = get_itbl((StgClosure *)sp);

	switch (info->type) {
	    
	case UPDATE_FRAME:
	case CATCH_FRAME:
        case UNDERFLOW_FRAME:
        case STOP_FRAME:
            printObj((StgClosure*)sp);
	    continue;

	case RET_DYN:
	{ 
	    StgRetDyn* r;
	    StgPtr p;
	    StgWord dyn;
	    nat size;

	    r = (StgRetDyn *)sp;
	    dyn = r->liveness;
	    debugBelch("RET_DYN (%p)\n", r);

	    p = (P_)(r->payload);
	    printSmallBitmap(spBottom, sp,
			     RET_DYN_LIVENESS(r->liveness), 
			     RET_DYN_BITMAP_SIZE);
	    p += RET_DYN_BITMAP_SIZE + RET_DYN_NONPTR_REGS_SIZE;

	    for (size = RET_DYN_NONPTRS(dyn); size > 0; size--) {
		debugBelch("   stk[%ld] (%p) = ", (long)(spBottom-p), p);
		debugBelch("Word# %ld\n", (long)*p);
		p++;
	    }
	
	    for (size = RET_DYN_PTRS(dyn); size > 0; size--) {
		debugBelch("   stk[%ld] (%p) = ", (long)(spBottom-p), p);
		printPtr(p);
		p++;
	    }
	    continue;
	}

	case RET_SMALL:
	    debugBelch("RET_SMALL (%p)\n", info);
	    bitmap = info->layout.bitmap;
	    printSmallBitmap(spBottom, sp+1, 
			     BITMAP_BITS(bitmap), BITMAP_SIZE(bitmap));
	    continue;

	case RET_BCO: {
	    StgBCO *bco;
	    
	    bco = ((StgBCO *)sp[1]);

	    debugBelch("RET_BCO (%p)\n", sp);
	    printLargeBitmap(spBottom, sp+2,
			     BCO_BITMAP(bco), BCO_BITMAP_SIZE(bco));
	    continue;
	}

	case RET_BIG:
	    barf("todo");

	case RET_FUN:
	{
	    StgFunInfoTable *fun_info;
	    StgRetFun *ret_fun;

	    ret_fun = (StgRetFun *)sp;
	    fun_info = get_fun_itbl(ret_fun->fun);
	    debugBelch("RET_FUN (%p) (type=%d)\n", ret_fun->fun, (int)fun_info->f.fun_type);
	    switch (fun_info->f.fun_type) {
	    case ARG_GEN:
		printSmallBitmap(spBottom, sp+2,
				 BITMAP_BITS(fun_info->f.b.bitmap),
				 BITMAP_SIZE(fun_info->f.b.bitmap));
		break;
	    case ARG_GEN_BIG:
		printLargeBitmap(spBottom, sp+2,
				 GET_FUN_LARGE_BITMAP(fun_info),
				 GET_FUN_LARGE_BITMAP(fun_info)->size);
		break;
	    default:
		printSmallBitmap(spBottom, sp+2,
				 BITMAP_BITS(stg_arg_bitmaps[fun_info->f.fun_type]),
				 BITMAP_SIZE(stg_arg_bitmaps[fun_info->f.fun_type]));
		break;
	    }
	    continue;
	}
	   
	default:
	    debugBelch("unknown object %d\n", (int)info->type);
	    barf("printStackChunk");
	}
    }
}
Ejemplo n.º 17
0
Archivo: Sanity.c Proyecto: Lemmih/ghc
// check an individual stack object
StgOffset 
checkStackFrame( StgPtr c )
{
    nat size;
    const StgRetInfoTable* info;

    info = get_ret_itbl((StgClosure *)c);

    /* All activation records have 'bitmap' style layout info. */
    switch (info->i.type) {

    case UPDATE_FRAME:
      ASSERT(LOOKS_LIKE_CLOSURE_PTR(((StgUpdateFrame*)c)->updatee));
    case ATOMICALLY_FRAME:
    case CATCH_RETRY_FRAME:
    case CATCH_STM_FRAME:
    case CATCH_FRAME:
      // small bitmap cases (<= 32 entries)
    case UNDERFLOW_FRAME:
    case STOP_FRAME:
    case RET_SMALL:
	size = BITMAP_SIZE(info->i.layout.bitmap);
	checkSmallBitmap((StgPtr)c + 1, 
			 BITMAP_BITS(info->i.layout.bitmap), size);
	return 1 + size;

    case RET_BCO: {
	StgBCO *bco;
	nat size;
	bco = (StgBCO *)*(c+1);
	size = BCO_BITMAP_SIZE(bco);
	checkLargeBitmap((StgPtr)c + 2, BCO_BITMAP(bco), size);
	return 2 + size;
    }

    case RET_BIG: // large bitmap (> 32 entries)
	size = GET_LARGE_BITMAP(&info->i)->size;
	checkLargeBitmap((StgPtr)c + 1, GET_LARGE_BITMAP(&info->i), size);
	return 1 + size;

    case RET_FUN:
    {
	StgFunInfoTable *fun_info;
	StgRetFun *ret_fun;

	ret_fun = (StgRetFun *)c;
	fun_info = get_fun_itbl(UNTAG_CLOSURE(ret_fun->fun));
	size = ret_fun->size;
	switch (fun_info->f.fun_type) {
	case ARG_GEN:
	    checkSmallBitmap((StgPtr)ret_fun->payload, 
			     BITMAP_BITS(fun_info->f.b.bitmap), size);
	    break;
	case ARG_GEN_BIG:
	    checkLargeBitmap((StgPtr)ret_fun->payload,
			     GET_FUN_LARGE_BITMAP(fun_info), size);
	    break;
	default:
	    checkSmallBitmap((StgPtr)ret_fun->payload,
			     BITMAP_BITS(stg_arg_bitmaps[fun_info->f.fun_type]),
			     size);
	    break;
	}
	return sizeofW(StgRetFun) + size;
    }

    default:
	barf("checkStackFrame: weird activation record found on stack (%p %d).",c,info->i.type);
    }
}
Ejemplo n.º 18
0
// check an individual stack object
StgOffset 
checkStackFrame( StgPtr c )
{
    nat size;
    const StgRetInfoTable* info;

    info = get_ret_itbl((StgClosure *)c);

    /* All activation records have 'bitmap' style layout info. */
    switch (info->i.type) {
    case RET_DYN: /* Dynamic bitmap: the mask is stored on the stack */
    {
	StgWord dyn;
	StgPtr p;
	StgRetDyn* r;
	
	r = (StgRetDyn *)c;
	dyn = r->liveness;
	
	p = (P_)(r->payload);
	checkSmallBitmap(p,RET_DYN_LIVENESS(r->liveness),RET_DYN_BITMAP_SIZE);
	p += RET_DYN_BITMAP_SIZE + RET_DYN_NONPTR_REGS_SIZE;

	// skip over the non-pointers
	p += RET_DYN_NONPTRS(dyn);
	
	// follow the ptr words
	for (size = RET_DYN_PTRS(dyn); size > 0; size--) {
	    checkClosureShallow((StgClosure *)*p);
	    p++;
	}
	
	return sizeofW(StgRetDyn) + RET_DYN_BITMAP_SIZE +
	    RET_DYN_NONPTR_REGS_SIZE +
	    RET_DYN_NONPTRS(dyn) + RET_DYN_PTRS(dyn);
    }

    case UPDATE_FRAME:
      ASSERT(LOOKS_LIKE_CLOSURE_PTR(((StgUpdateFrame*)c)->updatee));
    case ATOMICALLY_FRAME:
    case CATCH_RETRY_FRAME:
    case CATCH_STM_FRAME:
    case CATCH_FRAME:
      // small bitmap cases (<= 32 entries)
    case UNDERFLOW_FRAME:
    case STOP_FRAME:
    case RET_SMALL:
	size = BITMAP_SIZE(info->i.layout.bitmap);
	checkSmallBitmap((StgPtr)c + 1, 
			 BITMAP_BITS(info->i.layout.bitmap), size);
	return 1 + size;

    case RET_BCO: {
	StgBCO *bco;
	nat size;
	bco = (StgBCO *)*(c+1);
	size = BCO_BITMAP_SIZE(bco);
	checkLargeBitmap((StgPtr)c + 2, BCO_BITMAP(bco), size);
	return 2 + size;
    }

    case RET_BIG: // large bitmap (> 32 entries)
	size = GET_LARGE_BITMAP(&info->i)->size;
	checkLargeBitmap((StgPtr)c + 1, GET_LARGE_BITMAP(&info->i), size);
	return 1 + size;

    case RET_FUN:
    {
	StgFunInfoTable *fun_info;
	StgRetFun *ret_fun;

	ret_fun = (StgRetFun *)c;
	fun_info = get_fun_itbl(UNTAG_CLOSURE(ret_fun->fun));
	size = ret_fun->size;
	switch (fun_info->f.fun_type) {
	case ARG_GEN:
	    checkSmallBitmap((StgPtr)ret_fun->payload, 
			     BITMAP_BITS(fun_info->f.b.bitmap), size);
	    break;
	case ARG_GEN_BIG:
	    checkLargeBitmap((StgPtr)ret_fun->payload,
			     GET_FUN_LARGE_BITMAP(fun_info), size);
	    break;
	default:
	    checkSmallBitmap((StgPtr)ret_fun->payload,
			     BITMAP_BITS(stg_arg_bitmaps[fun_info->f.fun_type]),
			     size);
	    break;
	}
	return sizeofW(StgRetFun) + size;
    }

    default:
	barf("checkStackFrame: weird activation record found on stack (%p %d).",c,info->i.type);
    }
}
Ejemplo n.º 19
0
Archivo: Scav.c Proyecto: bogiebro/ghc
static void
scavenge_stack(StgPtr p, StgPtr stack_end)
{
  const StgRetInfoTable* info;
  StgWord bitmap;
  nat size;

  /* 
   * Each time around this loop, we are looking at a chunk of stack
   * that starts with an activation record. 
   */

  while (p < stack_end) {
    info  = get_ret_itbl((StgClosure *)p);
      
    switch (info->i.type) {
	
    case UPDATE_FRAME:
	// In SMP, we can get update frames that point to indirections
	// when two threads evaluate the same thunk.  We do attempt to
	// discover this situation in threadPaused(), but it's
	// possible that the following sequence occurs:
	//
	//        A             B
	//                  enter T
	//     enter T
	//     blackhole T
	//                  update T
	//     GC
	//
	// Now T is an indirection, and the update frame is already
	// marked on A's stack, so we won't traverse it again in
	// threadPaused().  We could traverse the whole stack again
	// before GC, but that seems like overkill.
	//
	// Scavenging this update frame as normal would be disastrous;
	// the updatee would end up pointing to the value.  So we
	// check whether the value after evacuation is a BLACKHOLE,
	// and if not, we change the update frame to an stg_enter
	// frame that simply returns the value.  Hence, blackholing is
        // compulsory (otherwise we would have to check for thunks
        // too).
        //
        // Note [upd-black-hole]
        // One slight hiccup is that the THUNK_SELECTOR machinery can
        // overwrite the updatee with an IND.  In parallel GC, this
        // could even be happening concurrently, so we can't check for
        // the IND.  Fortunately if we assume that blackholing is
        // happening (either lazy or eager), then we can be sure that
        // the updatee is never a THUNK_SELECTOR and we're ok.
        // NB. this is a new invariant: blackholing is not optional.
    {
        StgUpdateFrame *frame = (StgUpdateFrame *)p;
        StgClosure *v;

        evacuate(&frame->updatee);
        v = frame->updatee;
        if (GET_CLOSURE_TAG(v) != 0 ||
            (get_itbl(v)->type != BLACKHOLE)) {
            // blackholing is compulsory, see above.
            frame->header.info = (const StgInfoTable*)&stg_enter_checkbh_info;
        }
        ASSERT(v->header.info != &stg_TSO_info);
        p += sizeofW(StgUpdateFrame);
        continue;
    }

      // small bitmap (< 32 entries, or 64 on a 64-bit machine) 
    case CATCH_STM_FRAME:
    case CATCH_RETRY_FRAME:
    case ATOMICALLY_FRAME:
    case UNDERFLOW_FRAME:
    case STOP_FRAME:
    case CATCH_FRAME:
    case RET_SMALL:
	bitmap = BITMAP_BITS(info->i.layout.bitmap);
	size   = BITMAP_SIZE(info->i.layout.bitmap);
	// NOTE: the payload starts immediately after the info-ptr, we
	// don't have an StgHeader in the same sense as a heap closure.
	p++;
	p = scavenge_small_bitmap(p, size, bitmap);

    follow_srt:
	if (major_gc) 
	    scavenge_srt((StgClosure **)GET_SRT(info), info->i.srt_bitmap);
	continue;

    case RET_BCO: {
	StgBCO *bco;
	nat size;

	p++;
	evacuate((StgClosure **)p);
	bco = (StgBCO *)*p;
	p++;
	size = BCO_BITMAP_SIZE(bco);
	scavenge_large_bitmap(p, BCO_BITMAP(bco), size);
	p += size;
	continue;
    }

      // large bitmap (> 32 entries, or > 64 on a 64-bit machine) 
    case RET_BIG:
    {
	nat size;

	size = GET_LARGE_BITMAP(&info->i)->size;
	p++;
	scavenge_large_bitmap(p, GET_LARGE_BITMAP(&info->i), size);
	p += size;
	// and don't forget to follow the SRT 
	goto follow_srt;
    }

      // Dynamic bitmap: the mask is stored on the stack, and
      // there are a number of non-pointers followed by a number
      // of pointers above the bitmapped area.  (see StgMacros.h,
      // HEAP_CHK_GEN).
    case RET_DYN:
    {
	StgWord dyn;
	dyn = ((StgRetDyn *)p)->liveness;

	// traverse the bitmap first
	bitmap = RET_DYN_LIVENESS(dyn);
	p      = (P_)&((StgRetDyn *)p)->payload[0];
	size   = RET_DYN_BITMAP_SIZE;
	p = scavenge_small_bitmap(p, size, bitmap);

	// skip over the non-ptr words
	p += RET_DYN_NONPTRS(dyn) + RET_DYN_NONPTR_REGS_SIZE;
	
	// follow the ptr words
	for (size = RET_DYN_PTRS(dyn); size > 0; size--) {
	    evacuate((StgClosure **)p);
	    p++;
	}
	continue;
    }

    case RET_FUN:
    {
	StgRetFun *ret_fun = (StgRetFun *)p;
	StgFunInfoTable *fun_info;

	evacuate(&ret_fun->fun);
 	fun_info = get_fun_itbl(UNTAG_CLOSURE(ret_fun->fun));
	p = scavenge_arg_block(fun_info, ret_fun->payload);
	goto follow_srt;
    }

    default:
	barf("scavenge_stack: weird activation record found on stack: %d", (int)(info->i.type));
    }
  }		     
}
Ejemplo n.º 20
0
Archivo: Printer.c Proyecto: da-x/ghc
void
printStackChunk( StgPtr sp, StgPtr spBottom )
{
    StgWord bitmap;
    const StgInfoTable *info;

    ASSERT(sp <= spBottom);
    for (; sp < spBottom; sp += stack_frame_sizeW((StgClosure *)sp)) {

        info = get_itbl((StgClosure *)sp);

        switch (info->type) {

        case UPDATE_FRAME:
        case CATCH_FRAME:
        case UNDERFLOW_FRAME:
        case STOP_FRAME:
            printObj((StgClosure*)sp);
            continue;

        case RET_SMALL:
            debugBelch("RET_SMALL (%p)\n", info);
            bitmap = info->layout.bitmap;
            printSmallBitmap(spBottom, sp+1,
                             BITMAP_BITS(bitmap), BITMAP_SIZE(bitmap));
            continue;

        case RET_BCO: {
            StgBCO *bco;

            bco = ((StgBCO *)sp[1]);

            debugBelch("RET_BCO (%p)\n", sp);
            printLargeBitmap(spBottom, sp+2,
                             BCO_BITMAP(bco), BCO_BITMAP_SIZE(bco));
            continue;
        }

        case RET_BIG:
            barf("todo");

        case RET_FUN:
        {
            StgFunInfoTable *fun_info;
            StgRetFun *ret_fun;

            ret_fun = (StgRetFun *)sp;
            fun_info = get_fun_itbl(ret_fun->fun);
            debugBelch("RET_FUN (%p) (type=%d)\n", ret_fun->fun, (int)fun_info->f.fun_type);
            switch (fun_info->f.fun_type) {
            case ARG_GEN:
                printSmallBitmap(spBottom, sp+2,
                                 BITMAP_BITS(fun_info->f.b.bitmap),
                                 BITMAP_SIZE(fun_info->f.b.bitmap));
                break;
            case ARG_GEN_BIG:
                printLargeBitmap(spBottom, sp+2,
                                 GET_FUN_LARGE_BITMAP(fun_info),
                                 GET_FUN_LARGE_BITMAP(fun_info)->size);
                break;
            default:
                printSmallBitmap(spBottom, sp+2,
                                 BITMAP_BITS(stg_arg_bitmaps[fun_info->f.fun_type]),
                                 BITMAP_SIZE(stg_arg_bitmaps[fun_info->f.fun_type]));
                break;
            }
            continue;
        }

        default:
            debugBelch("unknown object %d\n", (int)info->type);
            barf("printStackChunk");
        }
    }
}
Ejemplo n.º 21
0
bool SaveYUV(const char *fileName, BYTE *data, int width, int height)
{
    if (!data)
        return false;

    int hWidth = width >> 1;
    int hHeight = height >> 1;
    size_t find = -1;
    std::string outputFile;

    BitmapPixel *luma = new BitmapPixel[BITMAP_SIZE(width, height)];
    BitmapPixel *chrom = new BitmapPixel[BITMAP_SIZE(width, height)];

    memset(luma, 0, BITMAP_SIZE(width, height) * sizeof(BitmapPixel));
    memset(chrom, 0, BITMAP_SIZE(hWidth, hHeight) * sizeof(BitmapPixel));

    for(int row = 0; row < height; ++row)
    {
        for(int col = 0; col < width; ++col)
        {
            int outputIdx = BITMAP_INDEX(col, row, width);
            int inputIdx = ((height - row - 1) * width) + col;

            luma[outputIdx].red = data[inputIdx];
            luma[outputIdx].green = data[inputIdx];
            luma[outputIdx].blue = data[inputIdx];
        }
    }

    data += width * height;

    outputFile = fileName;
    find = outputFile.find_last_of(".");

    outputFile.insert(find, "-");
    outputFile.insert(find+1, "y");

    if(!SaveBitmap(outputFile.c_str(), (BYTE *)luma, width, height))
    {
        delete [] luma;
        delete [] chrom;
        return false;
    }

    for(int row = 0; row < hHeight; ++row)
    {
        for(int col = 0; col < hWidth; ++col)
        {
            int outputIdx = BITMAP_INDEX(col, row, hWidth);
            int inputIdx = ((hHeight - row - 1) * hWidth) + col;

            chrom[outputIdx].red = data[inputIdx];
            chrom[outputIdx].green = 255 - data[inputIdx];
            chrom[outputIdx].blue = 0;
        }
    }

    data += hWidth * hHeight;

    outputFile = fileName;
    find = outputFile.find_last_of(".");

    outputFile.insert(find, "-");
    outputFile.insert(find+1, "u");

    if(!SaveBitmap(outputFile.c_str(), (BYTE *)chrom, hWidth, hHeight))
    {
        delete [] luma;
        delete [] chrom;
        return false;
    }

    for(int row = 0; row < hHeight; ++row)
    {
        for(int col = 0; col < hWidth; ++col)
        {
            int outputIdx = BITMAP_INDEX(col, row, hWidth);
            int inputIdx = ((hHeight - row - 1) * hWidth) + col;

            chrom[outputIdx].red = 0;
            chrom[outputIdx].green = 255 - data[inputIdx];
            chrom[outputIdx].blue = data[inputIdx];
        }
    }

    data += hWidth * hHeight;

    outputFile = fileName;
    find = outputFile.find_last_of(".");

    outputFile.insert(find, "-");
    outputFile.insert(find+1, "v");

    if(!SaveBitmap(outputFile.c_str(), (BYTE *)chrom, hWidth, hHeight))
    {
        delete [] luma;
        delete [] chrom;
        return false;
    }

    delete [] luma;
    delete [] chrom;
    return true;
}
Ejemplo n.º 22
0
static void
thread_stack(StgPtr p, StgPtr stack_end)
{
    const StgRetInfoTable* info;
    StgWord bitmap;
    nat size;
    
    // highly similar to scavenge_stack, but we do pointer threading here.
    
    while (p < stack_end) {

	// *p must be the info pointer of an activation
	// record.  All activation records have 'bitmap' style layout
	// info.
	//
	info  = get_ret_itbl((StgClosure *)p);
	
	switch (info->i.type) {
	    
	    // Dynamic bitmap: the mask is stored on the stack 
	case RET_DYN:
	{
	    StgWord dyn;
	    dyn = ((StgRetDyn *)p)->liveness;

	    // traverse the bitmap first
	    bitmap = RET_DYN_LIVENESS(dyn);
	    p      = (P_)&((StgRetDyn *)p)->payload[0];
	    size   = RET_DYN_BITMAP_SIZE;
	    while (size > 0) {
		if ((bitmap & 1) == 0) {
		    thread((StgClosure **)p);
		}
		p++;
		bitmap = bitmap >> 1;
		size--;
	    }
	    
	    // skip over the non-ptr words
	    p += RET_DYN_NONPTRS(dyn) + RET_DYN_NONPTR_REGS_SIZE;
	    
	    // follow the ptr words
	    for (size = RET_DYN_PTRS(dyn); size > 0; size--) {
		thread((StgClosure **)p);
		p++;
	    }
	    continue;
	}
	    
	    // small bitmap (<= 32 entries, or 64 on a 64-bit machine) 
	case UPDATE_FRAME:
	case STOP_FRAME:
	case CATCH_FRAME:
	case RET_SMALL:
	    bitmap = BITMAP_BITS(info->i.layout.bitmap);
	    size   = BITMAP_SIZE(info->i.layout.bitmap);
	    p++;
	    // NOTE: the payload starts immediately after the info-ptr, we
	    // don't have an StgHeader in the same sense as a heap closure.
	    while (size > 0) {
		if ((bitmap & 1) == 0) {
		    thread((StgClosure **)p);
		}
		p++;
		bitmap = bitmap >> 1;
		size--;
	    }
	    continue;

#ifdef ALLOW_INTERPRETER
	case RET_BCO: {
	    StgBCO *bco;
	    nat size;
	    
	    p++;
	    bco = (StgBCO *)*p;
	    thread((StgClosure **)p);
	    p++;
	    size = BCO_BITMAP_SIZE(bco);
	    thread_large_bitmap(p, BCO_BITMAP(bco), size);
	    p += size;
	    continue;
	}
#endif // ALLOW_INTERPRETER

	    // large bitmap (> 32 entries, or 64 on a 64-bit machine) 
	case RET_BIG:
	    p++;
	    size = GET_LARGE_BITMAP(&info->i)->size;
	    thread_large_bitmap(p, GET_LARGE_BITMAP(&info->i), size);
	    p += size;
	    continue;

	case RET_FUN:
	{
	    StgRetFun *ret_fun = (StgRetFun *)p;
	    StgFunInfoTable *fun_info;
	    
	    fun_info = FUN_INFO_PTR_TO_STRUCT(UNTAG_CLOSURE((StgClosure *)
                           get_threaded_info((StgPtr)ret_fun->fun)));
	         // *before* threading it!
	    thread(&ret_fun->fun);
	    p = thread_arg_block(fun_info, ret_fun->payload);
	    continue;
	}

	default:
	    barf("thread_stack: weird activation record found on stack: %d", 
		 (int)(info->i.type));
	}
    }
}
Ejemplo n.º 23
0
void
printStackChunk( StgPtr sp, StgPtr spBottom )
{
    StgWord bitmap;
    const StgInfoTable *info;

    ASSERT(sp <= spBottom);
    for (; sp < spBottom; sp += stack_frame_sizeW((StgClosure *)sp)) {

        info = get_itbl((StgClosure *)sp);

        switch (info->type) {

        case UPDATE_FRAME:
        case CATCH_FRAME:
        case UNDERFLOW_FRAME:
        case STOP_FRAME:
            printClosure((StgClosure*)sp);
            continue;

        case RET_SMALL: {
            StgWord c = *sp;
            if (c == (StgWord)&stg_ctoi_R1p_info) {
                debugBelch("tstg_ctoi_ret_R1p_info\n" );
            } else if (c == (StgWord)&stg_ctoi_R1n_info) {
                debugBelch("stg_ctoi_ret_R1n_info\n" );
            } else if (c == (StgWord)&stg_ctoi_F1_info) {
                debugBelch("stg_ctoi_ret_F1_info\n" );
            } else if (c == (StgWord)&stg_ctoi_D1_info) {
                debugBelch("stg_ctoi_ret_D1_info\n" );
            } else if (c == (StgWord)&stg_ctoi_V_info) {
                debugBelch("stg_ctoi_ret_V_info\n" );
            } else if (c == (StgWord)&stg_ap_v_info) {
                debugBelch("stg_ap_v_info\n" );
            } else if (c == (StgWord)&stg_ap_f_info) {
                debugBelch("stg_ap_f_info\n" );
            } else if (c == (StgWord)&stg_ap_d_info) {
                debugBelch("stg_ap_d_info\n" );
            } else if (c == (StgWord)&stg_ap_l_info) {
                debugBelch("stg_ap_l_info\n" );
            } else if (c == (StgWord)&stg_ap_n_info) {
                debugBelch("stg_ap_n_info\n" );
            } else if (c == (StgWord)&stg_ap_p_info) {
                debugBelch("stg_ap_p_info\n" );
            } else if (c == (StgWord)&stg_ap_pp_info) {
                debugBelch("stg_ap_pp_info\n" );
            } else if (c == (StgWord)&stg_ap_ppp_info) {
                debugBelch("stg_ap_ppp_info\n" );
            } else if (c == (StgWord)&stg_ap_pppp_info) {
                debugBelch("stg_ap_pppp_info\n" );
            } else if (c == (StgWord)&stg_ap_ppppp_info) {
                debugBelch("stg_ap_ppppp_info\n" );
            } else if (c == (StgWord)&stg_ap_pppppp_info) {
                debugBelch("stg_ap_pppppp_info\n" );
#ifdef PROFILING
            } else if (c == (StgWord)&stg_restore_cccs_info) {
                debugBelch("stg_restore_cccs_info\n" );
                fprintCCS(stderr, (CostCentreStack*)sp[1]);
                debugBelch("\n" );
                continue;
#endif
            } else {
                debugBelch("RET_SMALL (%p)\n", info);
            }
            bitmap = info->layout.bitmap;
            printSmallBitmap(spBottom, sp+1,
                             BITMAP_BITS(bitmap), BITMAP_SIZE(bitmap));
            continue;
        }

        case RET_BCO: {
            StgBCO *bco;

            bco = ((StgBCO *)sp[1]);

            debugBelch("RET_BCO (%p)\n", sp);
            printLargeBitmap(spBottom, sp+2,
                             BCO_BITMAP(bco), BCO_BITMAP_SIZE(bco));
            continue;
        }

        case RET_BIG:
            barf("todo");

        case RET_FUN:
        {
            const StgFunInfoTable *fun_info;
            StgRetFun *ret_fun;

            ret_fun = (StgRetFun *)sp;
            fun_info = get_fun_itbl(ret_fun->fun);
            debugBelch("RET_FUN (%p) (type=%d)\n", ret_fun->fun, (int)fun_info->f.fun_type);
            switch (fun_info->f.fun_type) {
            case ARG_GEN:
                printSmallBitmap(spBottom, sp+2,
                                 BITMAP_BITS(fun_info->f.b.bitmap),
                                 BITMAP_SIZE(fun_info->f.b.bitmap));
                break;
            case ARG_GEN_BIG:
                printLargeBitmap(spBottom, sp+2,
                                 GET_FUN_LARGE_BITMAP(fun_info),
                                 GET_FUN_LARGE_BITMAP(fun_info)->size);
                break;
            default:
                printSmallBitmap(spBottom, sp+2,
                                 BITMAP_BITS(stg_arg_bitmaps[fun_info->f.fun_type]),
                                 BITMAP_SIZE(stg_arg_bitmaps[fun_info->f.fun_type]));
                break;
            }
            continue;
        }

        default:
            debugBelch("unknown object %d\n", (int)info->type);
            barf("printStackChunk");
        }
    }
}
Ejemplo n.º 24
0
int 
draw_to_bmp (const char *file, struct draw *draw)
{
  FILE *fp;
  BITMAPFILEHEADER header;
  BITMAPINFOHEADER info;
  
  if ((fp = fopen (file, "wb")) == NULL)
  {
    ERROR ("Couldn't open %s for writing: %s\n", file, strerror (errno));
    
    return -1;
  }
  
  header.bfType = BM_MAGIC;
  header.bfSize = sizeof (BITMAPFILEHEADER) + sizeof (BITMAPINFOHEADER) +
                  BITMAP_SIZE (draw->width, draw->height, 24);
                  
  header.bfReserved1 = header.bfReserved2 = 0;
  header.bfOffBits   = sizeof (BITMAPFILEHEADER) + sizeof (BITMAPINFOHEADER);
  
  if (fwrite (&header, sizeof (BITMAPFILEHEADER), 1, fp) < 1)
  {
    ERROR ("Couldn't store header in %s: %s\n", file, strerror (errno));
    fclose (fp);
    
    return -1;
  }
  
  info.biSize          = sizeof (BITMAPINFOHEADER);
  info.biWidth         = draw->width;
  info.biHeight        = draw->height;
  info.biPlanes        = 1; /* It's ONE f*****g plane, no zero, you dumbass */
  info.biBitCount      = 24;
  info.biCompression   = 0;
  info.biSizeImage     = 0;
  info.biXPelsPerMeter = 0;
  info.biYPelsPerMeter = 0;
  info.biClrUsed       = 0;
  info.biClrImportant  = 0;
  
  if (fwrite (&info, sizeof (BITMAPINFOHEADER), 1, fp) < 1)
  {
    ERROR ("Couldn't store header in %s: %s\n", file, strerror (errno));
    fclose (fp);
    
    return -1;
  }
  
  if (fwrite (draw->pixels, draw->total_size, 1, fp) < 1)
  {
    ERROR ("Couldn't store data in %s: %s\n", file, strerror (errno));
    fclose (fp);
    
    return -1;
  }
  
  fclose (fp);
  
  return 0;  
}