예제 #1
0
bitmap_t *bitmap_resize(bitmap_t *bitmap, size_t old_size, size_t new_size)
{
	/* resize if mmap exists else new mmap */
	if (bitmap->array != NULL) {
		bitmap->array = mremap(bitmap->array, old_size, new_size,
					MREMAP_MAYMOVE);
		if (bitmap->array == MAP_FAILED) {
			perror("Error resizing mmap");
			free_bitmap(bitmap);
			return NULL;
		}
	}

	if (bitmap->array == NULL) {
		bitmap->array = mmap(0, new_size, PROT_READ | PROT_WRITE,
				MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
		if (bitmap->array == MAP_FAILED) {
			perror("Error init mmap");
			free_bitmap(bitmap);
			return NULL;
		}
	}

	bitmap->bytes = new_size;
	return bitmap;
}
예제 #2
0
int main()
{
	define_exp(exp);
	TRY(exp) {
		do_init();
		launch_resource_process();

		struct bitmap_t * b = load_bitmap("0*XP3:ss_保有背景真アサシン.tlg|FILE:/home/wn/Windows/Fate/image.xp3",
				NULL);
		struct bitmap_array_t * array = split_bitmap(b,
				128, 128, 1);
		if (array->original_bitmap == NULL) {
			free_bitmap(b);
		}
		struct rect_mesh_t * mesh = build_mesh_by_array(array);
		assert(mesh != NULL);

		VERBOSE(SYSTEM, "%dx%d\n", array->nr_w, array->nr_h);
		char name[128];
		for (volatile int j = 0; j < array->nr_h; j++) {
			for (volatile int i = 0; i < array->nr_w; i++) {
				snprintf(name, 128, "/tmp/%dx%d.png", j, i);
				define_exp(exp);
				catch_var(struct io_t *, writer, NULL);
				TRY(exp) {
					set_catched_var(writer, io_open_write("FILE", name));
					bitmap_to_png(&array->tiles[j * array->nr_w + i], writer);
				} FINALLY {
					get_catched_var(writer);
					if (writer != NULL)
						io_close(writer);
				} CATCH(exp) {
					RETHROW(exp);
				}
			}
		}

		print_rect_mesh(mesh);
		destroy_rect_mesh(mesh);

		if (array->original_bitmap != NULL) {
			free_bitmap(array->original_bitmap);
			free_bitmap_array(array);
		}

	} FINALLY {
		shutdown_resource_process();
		do_cleanup();
	} CATCH(exp) {
		
	}
	return 0;
}
예제 #3
0
파일: dablooms.c 프로젝트: trauzti/mimir
bitmap_t *bitmap_resize(bitmap_t *bitmap, size_t old_size, size_t new_size)
{
    int fd = bitmap->fd;
    struct stat fileStat;

    fstat(fd, &fileStat);
    size_t size = fileStat.st_size;

    /* grow file if necessary */
    if (size < new_size) {
        if (ftruncate(fd, new_size) < 0) {
            perror("Error increasing file size with ftruncate");
            free_bitmap(bitmap);
            close(fd);
            return NULL;
        }
    }
    lseek(fd, 0, SEEK_SET);

    /* resize if mmap exists and possible on this os, else new mmap */
    if (bitmap->array != NULL) {
#if __linux
        bitmap->array = (char *)mremap(bitmap->array, old_size, new_size, MREMAP_MAYMOVE);
        if (bitmap->array == MAP_FAILED) {
            perror("Error resizing mmap");
            free_bitmap(bitmap);
            close(fd);
            return NULL;
        }
#else
        if (munmap(bitmap->array, bitmap->bytes) < 0) {
            perror("Error unmapping memory");
            free_bitmap(bitmap);
            close(fd);
            return NULL;
        }
        bitmap->array = NULL;
#endif
    }
    if (bitmap->array == NULL) {
        bitmap->array = (char *)mmap(0, new_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
        if (bitmap->array == MAP_FAILED) {
            perror("Error init mmap");
            free_bitmap(bitmap);
            close(fd);
            return NULL;
        }
    }

    bitmap->bytes = new_size;
    return bitmap;
}
예제 #4
0
int main(int argc, char* argv[])
{
	if (argc < 2) {
		printf("Usage %s [taskid] [otherid...] \n", argv[0]);
		exit(1);
	}
	Bitmap* bitmap = init_bitmap();

	write2bitmap(bitmap, argv[1], 1);
	
	int i;
	for (i = 2; i < argc; i++) {
	}

	char* newFile = malloc(sizeof(argv[1]));
	strcpy(newFile, argv[1]);
	
	FILE* fh = fopen(strcat(newFile, "_diff"), "w");
	uint64_t offset;
	for (offset = 0; offset < bitmap->maxpos+1; offset++) {
		if (get_bit(bitmap, offset)) {
			fprintf(fh, "%u\n", offset);
		}
	}

	fclose(fh);
	
	free(newFile);

	free_bitmap(bitmap);

	return EXIT_SUCCESS;
}
예제 #5
0
void
revert_command (Widget w, XtPointer client_data, XtPointer call_data)
{
  char_type *c;
  font_type *f = (font_type *) client_data;
  charcode_type code = FONT_CURRENT_CHARCODE (*f);
  char_type *original = FONT_CHAR (*f, code);
  
  /* Set the pointer in the font structure to null, so `read_char' will
     have to reread the character.  */
  FONT_CHAR (*f, code) = NULL;
  
  /* Reread the character.  */
  c = read_char (*f, code);
  if (c == NULL)
    FATAL2 ("xbfe: Character %d has somehow been deleted from `%s'",
            FONT_CURRENT_CHARCODE (*f), FONT_NAME (*f));

  show_char (XtParent (w), f, c);

  /* Release the storage the current character is using.  We must do
     this after rereading the character from the font, so that the same
     memory is not used.  If that happens, `bitmap_set_values' thinks
     nothing has changed.  */
  free_bitmap (&BCHAR_BITMAP (*original));
  free (original);
}
예제 #6
0
int main(int ac, char **av)
{
	if(ac > 1)
	{
		param_t p;
		int       parse_ret;

		if((parse_ret = parse_opts(&p, ac, av)) < 0)
		{
			std::fprintf(stderr, USAGE, av[0]);
			if (ac == 1)
				return (EXIT_SUCCESS);
			return (EXIT_FAILURE);
		}
		disp_info_bmp(p.input_bitmap);
		write_page(&p);
		free_bitmap(p.input_bitmap);
	}
	else
	{
		QApplication app(ac, av);
		AscurpiQ     gui;

		gui.show();
		return app.exec();
	}
}
예제 #7
0
void
expand_command (Widget w, XtPointer client_data, XtPointer call_data)
{
  font_type *f = (font_type *) client_data;
  /* We must use `*bitmap' here, since the editable Bitmap is a child of
     the Viewport.  Incidentally, R3's XtNameToWidget won't work here.  */
  Widget bw = XtNameToWidget (XtParent (w), "*bitmap");
  bitmap_type *b = BitmapBits (bw);
  char_type *c = XTALLOC (1, char_type);
  
  /* Copy the current character, so the `*_set_values' commands can
     notice something is changed.  */
  *c = *FONT_CURRENT_CHAR (*f);

  /* Do the enlargement.  */
  BCHAR_BITMAP (*c) = enlarge_bitmap (*b);
  
  /* We have to increase the bounding box for the character.  The best
     way to do this is not obvious.  Right now, we arrange things so
     that the origin of the character does not move, i.e., the new row
     at the bottom is below the baseline, and the new column at the left
     is into the side bearing.  Perhaps we should have four separate
     expand commands (or something along those lines).  */
  BCHAR_SET_WIDTH (*c) += 2;
  BCHAR_MIN_COL (*c)--;
  BCHAR_MAX_COL (*c)++;
  BCHAR_MIN_ROW (*c)--;
  BCHAR_MAX_ROW (*c)++;

  /* Display the new values.  */
  show_char (XtParent (w), f, c);

  /* Free afterwards; see revert_command.  */
  free_bitmap (b);
}
예제 #8
0
int main(int argc, char **argv)
{
	int x = 0; int y = 0; int z = 0;
	struct BITMAP *test = NULL;
	
	
	test = create_bitmap(128, 48, 1);
	
	test->color_table[1]->r = 255;
	test->color_table[1]->g = 255;
	test->color_table[1]->b = 255;
	
	// Test everything out by writing my font out to the bitmap image
	// In 6 rows of 16 columns
	for(z = 0; z < 48; z+=8) // Cycle through the 6 rows
		for(y = 0; y < 8; y++) // 8 lines per character
			for (x = 0; x < 16; x++) // 16 characters per row (1bpp)
				*(test->pixelarray + x + (test->row_width * (47 - (y + z)))) = font[(y * 96) + x + (z*2)];
			
	write_bitmap_to_file(test, "test.bmp");
	
	
	free_bitmap(test);
	
	return TRUE;
}
예제 #9
0
static void mexit(void)
{
	/* free the hash table contents */
	long tmp_save, tmp_sum;
	
	nf_unregister_hook(&nf_in_ops);
	nf_unregister_hook(&nf_out_ops);
	
	if (kprobe_in_reged)
        unregister_jprobe(&jps_netif_receive_skb);
	
	flush_workqueue(skb_wq);
	clear_remainder_skb();
	destroy_workqueue(skb_wq);

	release_hash_table_cache();
	free_percpu_file();
	free_slab();
	free_bitmap();	
	tcp_free_sha1sig_pool();
	
	tmp_save = atomic64_read(&save_num);
	tmp_sum =  atomic64_read(&sum_num);

	if (tmp_sum > 0)
		printk(KERN_INFO "Cache ratio is:%ld%%", (tmp_save*100)/tmp_sum);
	
	printk(KERN_INFO "savenum is:%ld; sumnum is:%ld,%ld(Mb);\nExit %s.", tmp_save, tmp_sum, (tmp_sum /1024 /1024 *8), THIS_MODULE->name);
	
}
예제 #10
0
static void release_swap_writer(struct swap_map_handle *handle)
{
	if (handle->cur)
		free_page((unsigned long)handle->cur);
	handle->cur = NULL;
	if (handle->bitmap)
		free_bitmap(handle->bitmap);
	handle->bitmap = NULL;
}
예제 #11
0
파일: dablooms.c 프로젝트: chobie/dablooms
int free_scaling_bloom(scaling_bloom_t *bloom)
{
    int i;
    for (i = bloom->num_blooms - 1; i >= 0; i--) {
        free_counting_bloom(*(bloom->blooms + i));
    }
    free(bloom->blooms);
    free_bitmap(bloom->bitmap);
    free(bloom);
    return 0;
}
예제 #12
0
RepairPost::~RepairPost() {
  delete [] symbols;
  delete [] csymb_n;
  delete BRR;
  delete [] ptrs;
  
  delete BR_ptr_bitmap;

  delete [] lenPost;  /** len of each original posting-list */
  free_bitmap(); 
}
예제 #13
0
파일: dablooms.c 프로젝트: trauzti/mimir
int free_scaling_bloom(scaling_bloom_t *bloom)
{
    int i;
    for (i = bloom->num_blooms - 1; i >= 0; i--) {
        free(bloom->blooms[i]->hashes);
        bloom->blooms[i]->hashes = NULL;
        free(bloom->blooms[i]);
        bloom->blooms[i] = NULL;
    }
    free(bloom->blooms);
    free_bitmap(bloom->bitmap);
    free(bloom);
    return 0;
}
예제 #14
0
static int snapshot_release(struct inode *inode, struct file *filp)
{
    struct snapshot_data *data;

    swsusp_free();
    data = filp->private_data;
    free_all_swap_pages(data->swap, data->bitmap);
    free_bitmap(data->bitmap);
    if (data->frozen) {
        down(&pm_sem);
        thaw_processes();
        enable_nonboot_cpus();
        up(&pm_sem);
    }
    atomic_inc(&device_available);
    return 0;
}
예제 #15
0
/*===========================================================================*
 *				fs_inodewalker			     *
 *===========================================================================*/
int fs_inodewalker()
{
	/* Get the list of blocks in use by the system from the inode bitmap */
	printf("Inode Walker\n");
	printf("Getting super node from device %llu ...\n", fs_dev);
	type = IMAP;
	sb = get_super(fs_dev);
	read_super(sb);
	lsuper();
	init_global();
	imap_disk = alloc_bitmap(N_IMAP);
	printf("Loading inode bitmap from disk ...\n");
	get_bitmap(imap_disk, IMAP);
	printf(" done.\n");
	sleep(3);
	int *list_inodes = get_list_used(imap_disk, IMAP);
	free_bitmap(imap_disk);
	return 0;
}
예제 #16
0
struct bitmap_page *alloc_bitmap(unsigned int nr_bits)
{
	struct bitmap_page *bitmap, *bp;
	unsigned int n;

	if (!nr_bits)
		return NULL;

	bitmap = (struct bitmap_page *)get_zeroed_page(GFP_KERNEL);
	bp = bitmap;
	for (n = BITMAP_PAGE_BITS; n < nr_bits; n += BITMAP_PAGE_BITS) {
		bp->next = (struct bitmap_page *)get_zeroed_page(GFP_KERNEL);
		bp = bp->next;
		if (!bp) {
			free_bitmap(bitmap);
			return NULL;
		}
	}
	return bitmap;
}
예제 #17
0
/*===========================================================================*
 *				fs_zonewalker			     *
 *===========================================================================*/
int fs_zonewalker()
{
	/* Get the list of blocks used by the system from the zone bitmap */
	printf("Zone Walkder\n");
	printf("Getting super node from device %llu ...\n", fs_dev);
	type = ZMAP;
	sb = get_super(fs_dev);
	read_super(sb);
	lsuper();
	sleep(3);
	init_global();
	zmap_disk = alloc_bitmap(N_ZMAP);
	printf("Loading zone bitmap from disk ...\n");
	get_bitmap(zmap_disk, ZMAP);
	printf(" done.\n\n");
	sleep(3);
	//print_bitmap(zmap_disk);
	int* list = get_list_used(zmap_disk, ZMAP);
	free_bitmap(zmap_disk);
	return 0;
}
예제 #18
0
int sfs_remove(char *file){
	int index = -1;
	for (int i = 0; i < MAX_FD; i++){
		if (strcmp(file, root[i].fname) == 0){
			index = i;							//matching file with index i
		}
	}

	//If there is no file with that name
	if (index < 0){
		printf("No file to remove\n");
		return 0;

	//If there is a file with that name	
	} else {
		int inode_indx = root[index].inode;
		int block_location;
		if (inode_table[inode_indx].size > 0){	//if there are some blocks to free
			//Number of blocks the file spans across:
			int nmb_of_blocks = (inode_table[inode_indx].size / BLOCK_SIZE) + 1; 
			for (int i = 0; i<nmb_of_blocks; i++){
				block_location = fetch_block(inode_indx,i);
				free_bitmap(block_location);
			}
		}
		//CLOSE IF FILE IS OPEN
		for (int i = 0; i < MAX_FD; i++){		//check if we have a file opened linked to the same inode
			if (inode_indx == fd_table[i].inode) { //if we find an open file with same inode as the matched file
				sfs_fclose(i);
			}
		}
		//REMOVE FROM ROOT DIRECTORY
		root[index] = (dir){"", -1};
		//REINITIALIZE INODE
		inode_table[inode_indx] = (inode){0, 1, 1, 0, {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1}, -1};
		//FLUSH
		flush_to_disk(inode_indx, 0);
		return 0;
	}
}
예제 #19
0
static int minit(void)
{
	int err = 0;

	init_hash_parameters();

	if (0 > (err = init_some_parameters()))
		goto out;

	if (0 > (err = alloc_percpu_file()))
		goto err_alloc_file;

	if (0 > (err = alloc_slab()))
		goto err_alloc_slab;

	if (0 > (err = alloc_bitmap()))
		goto err_bitmap;

	if (0 > (err = initial_hash_table_cache()))
		goto err_hash_table_cache;

	printk(KERN_INFO "Start %s.", THIS_MODULE->name);

	if (0 > (err = nf_register_hook(&nf_out_ops))) {
		printk(KERN_ERR "Failed to register nf_out %s.\n", THIS_MODULE->name);
		goto err_nf_reg_out;
	}

	if (0 > (err = nf_register_hook(&nf_in_ops))) {
		printk(KERN_ERR "Failed to register nf_in %s.\n", THIS_MODULE->name);
		goto err_nf_reg_in;
	}    
	
	if (tcp_alloc_sha1sig_pool() == NULL) { 
		printk(KERN_ERR "Failed to alloc sha1 pool %s.\n", THIS_MODULE->name);
		goto err_sha1siq_pool;
	}   

	err = register_jprobe(&jps_netif_receive_skb);
    if (err < 0) {
        printk(KERN_ERR "Failed to register jprobe netif_receive_skb %s.\n", THIS_MODULE->name);
        goto out;
    }
    kprobe_in_reged = 1; 

	goto out;

err_sha1siq_pool:
	tcp_free_sha1sig_pool();
err_nf_reg_in:
	nf_unregister_hook(&nf_in_ops);
err_nf_reg_out:
	nf_unregister_hook(&nf_out_ops);
err_hash_table_cache:
	release_hash_table_cache();
err_bitmap:
	free_bitmap();
err_alloc_slab:
	free_slab();
err_alloc_file:
	free_percpu_file();
out:
	return err;    
}
예제 #20
0
static int snapshot_ioctl(struct inode *inode, struct file *filp,
                          unsigned int cmd, unsigned long arg)
{
	int error = 0;
	struct snapshot_data *data;
	loff_t avail;
	sector_t offset;

	if (_IOC_TYPE(cmd) != SNAPSHOT_IOC_MAGIC)
		return -ENOTTY;
	if (_IOC_NR(cmd) > SNAPSHOT_IOC_MAXNR)
		return -ENOTTY;
	if (!capable(CAP_SYS_ADMIN))
		return -EPERM;

	data = filp->private_data;

	switch (cmd) {

	case SNAPSHOT_FREEZE:
		if (data->frozen)
			break;
		mutex_lock(&pm_mutex);
		if (freeze_processes()) {
			thaw_processes();
			error = -EBUSY;
		}
		mutex_unlock(&pm_mutex);
		if (!error)
			data->frozen = 1;
		break;

	case SNAPSHOT_UNFREEZE:
		if (!data->frozen)
			break;
		mutex_lock(&pm_mutex);
		thaw_processes();
		mutex_unlock(&pm_mutex);
		data->frozen = 0;
		break;

	case SNAPSHOT_ATOMIC_SNAPSHOT:
		if (data->mode != O_RDONLY || !data->frozen  || data->ready) {
			error = -EPERM;
			break;
		}
		error = snapshot_suspend(data->platform_suspend);
		if (!error)
			error = put_user(in_suspend, (unsigned int __user *)arg);
		if (!error)
			data->ready = 1;
		break;

	case SNAPSHOT_ATOMIC_RESTORE:
		snapshot_write_finalize(&data->handle);
		if (data->mode != O_WRONLY || !data->frozen ||
		    !snapshot_image_loaded(&data->handle)) {
			error = -EPERM;
			break;
		}
		error = snapshot_restore(data->platform_suspend);
		break;

	case SNAPSHOT_FREE:
		swsusp_free();
		memset(&data->handle, 0, sizeof(struct snapshot_handle));
		data->ready = 0;
		break;

	case SNAPSHOT_SET_IMAGE_SIZE:
		image_size = arg;
		break;

	case SNAPSHOT_AVAIL_SWAP:
		avail = count_swap_pages(data->swap, 1);
		avail <<= PAGE_SHIFT;
		error = put_user(avail, (loff_t __user *)arg);
		break;

	case SNAPSHOT_GET_SWAP_PAGE:
		if (data->swap < 0 || data->swap >= MAX_SWAPFILES) {
			error = -ENODEV;
			break;
		}
		if (!data->bitmap) {
			data->bitmap = alloc_bitmap(count_swap_pages(data->swap, 0));
			if (!data->bitmap) {
				error = -ENOMEM;
				break;
			}
		}
		offset = alloc_swapdev_block(data->swap, data->bitmap);
		if (offset) {
			offset <<= PAGE_SHIFT;
			error = put_user(offset, (sector_t __user *)arg);
		} else {
			error = -ENOSPC;
		}
		break;

	case SNAPSHOT_FREE_SWAP_PAGES:
		if (data->swap < 0 || data->swap >= MAX_SWAPFILES) {
			error = -ENODEV;
			break;
		}
		free_all_swap_pages(data->swap, data->bitmap);
		free_bitmap(data->bitmap);
		data->bitmap = NULL;
		break;

	case SNAPSHOT_SET_SWAP_FILE:
		if (!data->bitmap) {
			/*
			 * User space encodes device types as two-byte values,
			 * so we need to recode them
			 */
			if (old_decode_dev(arg)) {
				data->swap = swap_type_of(old_decode_dev(arg),
							0, NULL);
				if (data->swap < 0)
					error = -ENODEV;
			} else {
				data->swap = -1;
				error = -EINVAL;
			}
		} else {
			error = -EPERM;
		}
		break;

	case SNAPSHOT_S2RAM:
		if (!pm_ops) {
			error = -ENOSYS;
			break;
		}

		if (!data->frozen) {
			error = -EPERM;
			break;
		}

		if (!mutex_trylock(&pm_mutex)) {
			error = -EBUSY;
			break;
		}

		if (pm_ops->prepare) {
			error = pm_ops->prepare(PM_SUSPEND_MEM);
			if (error)
				goto OutS3;
		}

		/* Put devices to sleep */
		suspend_console();
		error = device_suspend(PMSG_SUSPEND);
		if (error) {
			printk(KERN_ERR "Failed to suspend some devices.\n");
		} else {
			/* Enter S3, system is already frozen */
			suspend_enter(PM_SUSPEND_MEM);

			/* Wake up devices */
			device_resume();
		}
		resume_console();
		if (pm_ops->finish)
			pm_ops->finish(PM_SUSPEND_MEM);

 OutS3:
		mutex_unlock(&pm_mutex);
		break;

	case SNAPSHOT_PMOPS:
		error = -EINVAL;

		switch (arg) {

		case PMOPS_PREPARE:
			if (pm_ops && pm_ops->enter) {
				data->platform_suspend = 1;
				error = 0;
			} else {
				error = -ENOSYS;
			}
			break;

		case PMOPS_ENTER:
			if (data->platform_suspend) {
				disable_nonboot_cpus();
				kernel_shutdown_prepare(SYSTEM_SUSPEND_DISK);
				error = pm_ops->enter(PM_SUSPEND_DISK);
				enable_nonboot_cpus();
			}
			break;

		case PMOPS_FINISH:
			if (data->platform_suspend)
				error = 0;

			break;

		default:
			printk(KERN_ERR "SNAPSHOT_PMOPS: invalid argument %ld\n", arg);

		}
		break;

	case SNAPSHOT_SET_SWAP_AREA:
		if (data->bitmap) {
			error = -EPERM;
		} else {
			struct resume_swap_area swap_area;
			dev_t swdev;

			error = copy_from_user(&swap_area, (void __user *)arg,
					sizeof(struct resume_swap_area));
			if (error) {
				error = -EFAULT;
				break;
			}

			/*
			 * User space encodes device types as two-byte values,
			 * so we need to recode them
			 */
			swdev = old_decode_dev(swap_area.dev);
			if (swdev) {
				offset = swap_area.offset;
				data->swap = swap_type_of(swdev, offset, NULL);
				if (data->swap < 0)
					error = -ENODEV;
			} else {
				data->swap = -1;
				error = -EINVAL;
			}
		}
		break;

	default:
		error = -ENOTTY;

	}

	return error;
}
예제 #21
0
파일: scan.c 프로젝트: dluco/ttf
int scan_glyph(TTF_Font *font, TTF_Glyph *glyph) {
	CHECKPTR(font);
	CHECKPTR(glyph);

	RETINIT(SUCCESS);

	if (!glyph->outline) {
		warn("failed to scan uninitialized glyph outline");
		return FAILURE;
	} else if (glyph->outline->point < 0) {
		warn("failed to scan unscaled glyph outline");
		return FAILURE;
	} else if (glyph->number_of_contours == 0) {
		/* Zero-length glyph with no outline. */
		return SUCCESS;
	}

	TTF_Outline *outline = glyph->outline;
	TTF_Bitmap *bitmap = NULL;
	uint32_t bg, fg;

	if (font->raster_flags & RENDER_FPAA) {
		/* Anti-aliased rendering - oversample outline then downsample. */
		bg = 0xFFFFFF;
		fg = 0x000000;
		if (!glyph->bitmap) {
			glyph->bitmap = create_bitmap((outline->x_max - outline->x_min) / 2,
					(outline->y_max - outline->y_min) / 2, bg);
		}

		/* Intermediate oversampled bitmap. */
		bitmap = create_bitmap(outline->x_max - outline->x_min,
				outline->y_max - outline->y_min, bg);
	} else if (font->raster_flags & RENDER_ASPAA) {
		/* Sub-pixel rendering - oversample in x-direction then downsample. */
		bg = 0xFFFFFF;
		fg = 0x000000;
		if (!glyph->bitmap) {
			glyph->bitmap = create_bitmap((outline->x_max - outline->x_min) / 3,
					outline->y_max - outline->y_min, bg);
		}

		/* Intermediate oversampled bitmap. */
		bitmap = create_bitmap(outline->x_max - outline->x_min,
				outline->y_max - outline->y_min, bg);
	} else {
		/* Normal rendering - write directly to glyph bitmap. */
		bg = 0xFFFFFF;
		fg = 0x000000;
		if (!glyph->bitmap) {
			glyph->bitmap = create_bitmap(outline->x_max - outline->x_min,
					outline->y_max - outline->y_min, bg);
		}

		bitmap = glyph->bitmap;
	}

	/* Create a scan-line for each row in the scaled outline. */
	int num_scanlines = outline->y_max - outline->y_min;
	TTF_Scan_Line *scanlines = malloc(num_scanlines * sizeof(*scanlines));
	CHECKFAIL(scanlines, warnerr("failed to alloc glyph scan lines"));

	/* Find intersections of each scan-line with contour segments. */
	for (int i = 0; i < num_scanlines; i++) {
		TTF_Scan_Line *scanline = &scanlines[i];
		init_scanline(scanline, outline->num_contours * 2);
		scanline->y = outline->y_max - i;

		for (int j = 0; j < outline->num_contours; j++) {
			TTF_Contour *contour = &outline->contours[j];
			int k;
			for (k = 0; k < contour->num_segments; k++) {
				TTF_Segment *segment = &contour->segments[k];
				intersect_segment(segment, scanline);
			}
		}

		/* Round pixel intersection values to 1/64 of a pixel. */
		for (int j = 0; j < scanline->num_intersections; j++) {
			scanline->x[j] = round_pixel(scanline->x[j]);
		}

		/* Sort intersections from left to right. */
		qsort(scanline->x, scanline->num_intersections, sizeof(*scanline->x), cmp_intersections);

//		printf("Intersections: ");
//		char *sep = "";
//		for (int j = 0; j < scanline->num_intersections; j++) {
//			printf("%s%f", sep, scanline->x[j]);
//			sep = ", ";
//		}
//		printf("\n");

		int int_index = 0, fill = 0;
		for (int j = 0; j < bitmap->w; j++) {
			if (int_index < scanline->num_intersections) {
				if ((outline->x_min + j) >= scanline->x[int_index]) {
					fill = !fill;

					/* Skip over duplicate intersections. */
					int k;
					for (k = 1; int_index+k < scanline->num_intersections; k++) {
						if (scanline->x[int_index] != scanline->x[int_index+k]) {
							break;
						}
					}
					int_index += k;
				}
			}
			if (fill) {
				bitmap_set(bitmap, j, i, fg);
			}
		}
	}

	if (font->raster_flags & RENDER_FPAA) {
		/* Downsample intermediate bitmap. */
		for (int y = 0; y < glyph->bitmap->h; y++) {
			for (int x = 0; x < glyph->bitmap->w; x++) {
				/* Calculate pixel coverage:
				 * 	coverage = number filled samples / number samples */
				float coverage = 0;
				if (bitmap_get(bitmap, (2*x), (2*y)) == 0x000000) coverage++;
				if (bitmap_get(bitmap, (2*x)+1, (2*y)) == 0x000000) coverage++;
				if (bitmap_get(bitmap, (2*x), (2*y)+1) == 0x000000) coverage++;
				if (bitmap_get(bitmap, (2*x)+1, (2*y)+1) == 0x000000) coverage++;
				coverage /= 4;
				uint8_t shade = 0xFF*(1-coverage);
				uint32_t pixel = (shade << 16) | (shade << 8) | (shade << 0);

				bitmap_set(glyph->bitmap, x, y, pixel);
			}
		}

		free_bitmap(bitmap);
	} else if (font->raster_flags & RENDER_ASPAA) {
		/* Perform five element low-pass filter. */
		TTF_Bitmap *temp = create_bitmap(bitmap->w, bitmap->h, bg);

		for (int y = 0; y < bitmap->h; y++) {
			for (int x = 0; x < bitmap->w; x++) {
				uint32_t pixel = 0x000000;

				pixel += bitmap_get(bitmap, x-2, y) * (1.0 / 9.0);
				pixel += bitmap_get(bitmap, x-1, y) * (2.0 / 9.0);
				pixel += bitmap_get(bitmap, x, y) * (3.0 / 9.0);
				pixel += bitmap_get(bitmap, x+1, y) * (2.0 / 9.0);
				pixel += bitmap_get(bitmap, x+2, y) * (1.0 / 9.0);

				bitmap_set(temp, x, y, pixel);
			}
		}

		free_bitmap(bitmap);
		bitmap = temp;

		/* Downsample intermediate bitmap. */
		for (int y = 0; y < glyph->bitmap->h; y++) {
			for (int x = 0; x < glyph->bitmap->w; x++) {
				uint8_t r, g, b;
				r = (bitmap_get(bitmap, (3*x), y) * 0xFF) / 0xFFFFFF;
				g = (bitmap_get(bitmap, (3*x)+1, y) * 0xFF) / 0xFFFFFF;
				b = (bitmap_get(bitmap, (3*x)+2, y) * 0xFF) / 0xFFFFFF;
				uint32_t pixel = (r << 16) | (g << 8) | (b << 0);

				bitmap_set(glyph->bitmap, x, y, pixel);
			}
		}

		free_bitmap(bitmap);
	}

	RETRELEASE(free_scanlines(scanlines, num_scanlines));
}
예제 #22
0
파일: bitmap.c 프로젝트: Eleanor66613/CS131
void 
at_bitmap_free (at_bitmap_type * bitmap)
{
    free_bitmap (bitmap);
    free(bitmap);
}
예제 #23
0
파일: main.c 프로젝트: apinkney97/JSReflow
void
main (int argc, string argv[])
{
  int code;
  string font_name = read_command_line (argc, argv);
  bitmap_font_type f = get_bitmap_font (font_name, atou (dpi));
  string font_basename = basename (font_name);

  /* Initializing the display might involve forking a process.  We
     wouldn't want that process to get copies of open output files,
     since then when it exited, random stuff might get written to the
     end of the file.  */
  init_display (f);

  if (logging)
    log_file = xfopen (concat (font_basename, ".log"), "w");

  if (strlen (BITMAP_FONT_COMMENT (f)) > 0)
    REPORT1 ("{%s}\n", BITMAP_FONT_COMMENT (f));

  if (output_name == NULL)
    output_name = font_basename;

  bzr_start_output (output_name, f);

  /* The main loop: for each character, find the outline of the shape,
     then fit the splines to it.  */
  for (code = starting_char; code <= ending_char; code++)
    {
      pixel_outline_list_type pixels;
      spline_list_array_type splines;
      char_info_type *c = get_char (font_name, code);
    
      if (c == NULL) continue;

      REPORT1 ("[%u ", code);
      if (logging)
	{
	  LOG ("\n\n\f");
	  print_char (log_file, *c);
	}

      x_start_char (*c);
      pixels = find_outline_pixels (*c);
      /* `find_outline_pixels' uses corners as the coordinates, instead
         of the pixel centers.  So we have to increase the bounding box.  */
      CHAR_MIN_COL (*c)--; CHAR_MAX_COL (*c)++;
      CHAR_MIN_ROW (*c)--; CHAR_MAX_ROW (*c)++;

      REPORT ("|");
      splines = fitted_splines (pixels);

      bzr_output_char (*c, splines);
      
      /* Flush output before displaying the character, in case the user
         is interested in looking at it and the online version
         simultaneously.  */
      flush_log_output ();

      x_output_char (*c, splines);
      REPORT ("]\n");

      /* If the character was empty, it won't have a bitmap.  */
      if (BITMAP_BITS (CHAR_BITMAP (*c)) != NULL)
        free_bitmap (&CHAR_BITMAP (*c));

      free_pixel_outline_list (&pixels);
      free_spline_list_array (&splines);
    }

  bzr_finish_output ();
  close_display ();

  close_font (font_name);

  exit (0);
}
예제 #24
0
int main(int argc, char **argv)
{
    Job job;
    int i;
    FILE *pjf;

    init_job(&job);
    job.core = create_core();
    
    for (i = 1; i < argc; i++)
    {
        char *opt = argv[i];
        char *arg = argv[i + 1];
        if (opt[0] == '-' && strcmp(opt, "-"))
        {
            if (!strcmp(opt, "-L") || !strcmp(opt, "--letter"))
            {
                job.just_one_letter = 1;
                job.just_one_word = 0;
            }
            if (!strcmp(opt, "-t") || !strcmp(opt, "--truth"))
            {
                i++; if (!arg) usage();
                job.just_one_letter = 1;
                job.just_one_word = 0;
                job.ground_truth = arg;
            }
            if (!strcmp(opt, "-a") || !strcmp(opt, "--append"))
            {
                job.append = 1;
            }
            else if (!strcmp(opt, "-W") || !strcmp(opt, "--word"))
            {
                job.just_one_letter = 0;
                job.just_one_word = 1;
            }
            else if (!strcmp(opt, "-l") || !strcmp(opt, "--lib"))
            {
                Library l;
                i++; if (!arg) usage();
                l = library_open(arg);
                library_discard_prototypes(l);
                add_to_core(job.core, l);
            }
            else if (!strcmp(opt, "-p") || !strcmp(opt, "-j") || !strcmp(opt, "--pjf"))
            {
                i++; if (!arg) usage();
                job.job_file_path = arg;
            }
            else if (!strcmp(opt, "-i") || !strcmp(opt, "--in"))
            {
                i++; if (!arg) usage();
                job.input_path = arg;                
            }
            else if (!strcmp(opt, "-o") || !strcmp(opt, "--out"))
            {
                i++; if (!arg) usage();
                set_core_orange_policy(job.core, 1);
                job.out_library_path = arg;
            }
            else if (!strcmp(opt, "-c") || !strcmp(opt, "--color"))
            {
                job.colored_output = 1;
            }
            else if (!strcmp(opt, "-n") || !strcmp(opt, "--nocolor"))
            {
                job.colored_output = 0;
            }
        }
    }


    load_image(&job);

    if (job.just_one_letter)
    {
        process_letter(&job, 0, 0, job.width, job.height);
        putchar('\n');
        if (job.ground_truth && job.out_library_path)
        {
            Library l = get_core_orange_library(job.core);
            if (library_shelves_count(l))
            {
                Shelf *s = library_get_shelf(l, 0);
                if (s->count)
                {
                    strncpy(s->records[0].text, job.ground_truth, MAX_TEXT_SIZE);
                }
            }
        }
    }
    else if (job.just_one_word)
    {
        process_word(&job, 0, 0, job.width, job.height);
        putchar('\n');
    }
    else 
    {
        if (!job.job_file_path)
        {
            fprintf(stderr, "You must specify a pjf file (or either -L or -W).\n");
            usage();
        }
        pjf = fopen(job.job_file_path, "r");
        if (!pjf)
        {
            perror(job.job_file_path);
            exit(1);
        }
        go(&job, pjf);
    }

    if (job.out_library_path)
        library_save(get_core_orange_library(job.core), job.out_library_path, job.append);

    free_bitmap(job.pixels);
    free_core(job.core);
    return 0;
}
예제 #25
0
static int snapshot_ioctl(struct inode *inode, struct file *filp,
                          unsigned int cmd, unsigned long arg)
{
    int error = 0;
    struct snapshot_data *data;
    loff_t offset, avail;

    if (_IOC_TYPE(cmd) != SNAPSHOT_IOC_MAGIC)
        return -ENOTTY;
    if (_IOC_NR(cmd) > SNAPSHOT_IOC_MAXNR)
        return -ENOTTY;
    if (!capable(CAP_SYS_ADMIN))
        return -EPERM;

    data = filp->private_data;

    switch (cmd) {

    case SNAPSHOT_FREEZE:
        if (data->frozen)
            break;
        down(&pm_sem);
        disable_nonboot_cpus();
        if (freeze_processes()) {
            thaw_processes();
            enable_nonboot_cpus();
            error = -EBUSY;
        }
        up(&pm_sem);
        if (!error)
            data->frozen = 1;
        break;

    case SNAPSHOT_UNFREEZE:
        if (!data->frozen)
            break;
        down(&pm_sem);
        thaw_processes();
        enable_nonboot_cpus();
        up(&pm_sem);
        data->frozen = 0;
        break;

    case SNAPSHOT_ATOMIC_SNAPSHOT:
        if (data->mode != O_RDONLY || !data->frozen  || data->ready) {
            error = -EPERM;
            break;
        }
        down(&pm_sem);
        /* Free memory before shutting down devices. */
        error = swsusp_shrink_memory();
        if (!error) {
            error = device_suspend(PMSG_FREEZE);
            if (!error) {
                in_suspend = 1;
                error = swsusp_suspend();
                device_resume();
            }
        }
        up(&pm_sem);
        if (!error)
            error = put_user(in_suspend, (unsigned int __user *)arg);
        if (!error)
            data->ready = 1;
        break;

    case SNAPSHOT_ATOMIC_RESTORE:
        if (data->mode != O_WRONLY || !data->frozen ||
                !snapshot_image_loaded(&data->handle)) {
            error = -EPERM;
            break;
        }
        down(&pm_sem);
        pm_prepare_console();
        error = device_suspend(PMSG_FREEZE);
        if (!error) {
            error = swsusp_resume();
            device_resume();
        }
        pm_restore_console();
        up(&pm_sem);
        break;

    case SNAPSHOT_FREE:
        swsusp_free();
        memset(&data->handle, 0, sizeof(struct snapshot_handle));
        data->ready = 0;
        break;

    case SNAPSHOT_SET_IMAGE_SIZE:
        image_size = arg;
        break;

    case SNAPSHOT_AVAIL_SWAP:
        avail = count_swap_pages(data->swap, 1);
        avail <<= PAGE_SHIFT;
        error = put_user(avail, (loff_t __user *)arg);
        break;

    case SNAPSHOT_GET_SWAP_PAGE:
        if (data->swap < 0 || data->swap >= MAX_SWAPFILES) {
            error = -ENODEV;
            break;
        }
        if (!data->bitmap) {
            data->bitmap = alloc_bitmap(count_swap_pages(data->swap, 0));
            if (!data->bitmap) {
                error = -ENOMEM;
                break;
            }
        }
        offset = alloc_swap_page(data->swap, data->bitmap);
        if (offset) {
            offset <<= PAGE_SHIFT;
            error = put_user(offset, (loff_t __user *)arg);
        } else {
            error = -ENOSPC;
        }
        break;

    case SNAPSHOT_FREE_SWAP_PAGES:
        if (data->swap < 0 || data->swap >= MAX_SWAPFILES) {
            error = -ENODEV;
            break;
        }
        free_all_swap_pages(data->swap, data->bitmap);
        free_bitmap(data->bitmap);
        data->bitmap = NULL;
        break;

    case SNAPSHOT_SET_SWAP_FILE:
        if (!data->bitmap) {
            /*
             * User space encodes device types as two-byte values,
             * so we need to recode them
             */
            if (old_decode_dev(arg)) {
                data->swap = swap_type_of(old_decode_dev(arg));
                if (data->swap < 0)
                    error = -ENODEV;
            } else {
                data->swap = -1;
                error = -EINVAL;
            }
        } else {
            error = -EPERM;
        }
        break;

    case SNAPSHOT_S2RAM:
        if (!data->frozen) {
            error = -EPERM;
            break;
        }

        if (down_trylock(&pm_sem)) {
            error = -EBUSY;
            break;
        }

        if (pm_ops->prepare) {
            error = pm_ops->prepare(PM_SUSPEND_MEM);
            if (error)
                goto OutS3;
        }

        /* Put devices to sleep */
        error = device_suspend(PMSG_SUSPEND);
        if (error) {
            printk(KERN_ERR "Failed to suspend some devices.\n");
        } else {
            /* Enter S3, system is already frozen */
            suspend_enter(PM_SUSPEND_MEM);

            /* Wake up devices */
            device_resume();
        }

        if (pm_ops->finish)
            pm_ops->finish(PM_SUSPEND_MEM);

OutS3:
        up(&pm_sem);
        break;

    default:
        error = -ENOTTY;

    }

    return error;
}
예제 #26
0
int main(int argc,char **argv) {
    WNDCLASS wnd;
    HRESULT hr;
    RECT rect;
    MSG msg;
    char *a;
    int i;

    for (i=1;i < argc;) {
        a = argv[i++];

        if (*a == '-') {
            do { a++; } while (*a == '-');

            if (!strcmp(a,"nodpiaware")) {
                gdi_no_dpiaware = true;
            }
            else if (!strcmp(a,"dpiaware")) {
                gdi_no_dpiaware = false;
            }
            else {
                fprintf(stderr,"Unhandled switch %s\n",a);
                return 1;
            }
        }
        else {
            fprintf(stderr,"Unhandled arg %s\n",a);
            return 1;
        }
    }

    if (sizeof(rgb24bpp_t) != 3)
        fprintf(stderr,"WARNING: uint24_t is not 3 bytes long, it is %u bytes\n",(unsigned int)sizeof(rgb24bpp_t));

    /* Please don't scale me in the name of "DPI awareness" */
    if (!gdi_no_dpiaware)
        win32_dpi_aware();

    /* Bring up DirectX */
    /* NTS: On multi-monitor setups, this will create an "emulated" object. Hardware accel won't be possible unless we enum monitors. */
    if ((hr=DirectDrawCreate(NULL,&ddraw1,NULL)) != DD_OK) {
        fprintf(stderr,"DirectDrawCreate failed, HRESULT=0x%08lx\n",hr);
        return 1;
    }
    if ((hr=ddraw1->QueryInterface(IID_IDirectDraw2,(void**)(&ddraw))) != S_OK) {
        fprintf(stderr,"Unable to query IDirectDraw2 from IDirectDraw, HR=0x%08lx\n",hr);
        return 1;
    }
    ddraw1->Release();
    ddraw1 = NULL;
    if ((hr=ddraw->SetCooperativeLevel(hwndMain,ddrawCooperativeLevel=DDSCL_NORMAL)) != DD_OK) {
        fprintf(stderr,"Unable to ask for Normal cooperative mode, HR=0x%08lx\n",hr);
        return 1;
    }

    myInstance = GetModuleHandle(NULL);

    memset(&wnd,0,sizeof(wnd));
    wnd.lpfnWndProc = WndProc;
    wnd.hInstance = myInstance;
    wnd.lpszClassName = hwndMainClass;
    wnd.hCursor = LoadCursor(NULL,IDC_ARROW);

    if (!RegisterClass(&wnd)) {
        fprintf(stderr,"RegisterClass() failed\n");
        return 1;
    }

    rect.top = 0;
    rect.left = 0;
    rect.right = 640;
    rect.bottom = 480;
    AdjustWindowRect(&rect,WS_OVERLAPPEDWINDOW,FALSE);

    hwndMain = CreateWindow(hwndMainClass,hwndMainTitle,
        hwndMainStyle=WS_OVERLAPPEDWINDOW,
        CW_USEDEFAULT,CW_USEDEFAULT,
        rect.right - rect.left,rect.bottom - rect.top,
        NULL,NULL,
        myInstance,NULL);
    if (!hwndMain) {
        fprintf(stderr,"CreateWindow() failed\n");
        return 1;
    }

    if (!init_dx_primary_surface()) {
        fprintf(stderr,"Failed to init primary surface\n");
        return 1;
    }

    GetClientRect(hwndMain,&rect);
    if (!init_bitmap(rect.right,rect.bottom)) {
        fprintf(stderr,"nit_bitmap() failed for %ux%u\n",(unsigned int)rect.right,(unsigned int)rect.bottom);
        return 1;
    }
    if (lock_bitmap()) {
        render_pattern(dx_bitmap);
        unlock_bitmap();
    }

    ShowWindow(hwndMain,SW_SHOW);
    UpdateWindow(hwndMain);

    while (GetMessage(&msg,NULL,0,0)) {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

    free_dx_primary_surface();
    free_bitmap();
    if (ddraw != NULL) {
        ddraw->RestoreDisplayMode();
        ddraw->Release();
        ddraw = NULL;
    }

    if (menuDisplayModes != NULL) {
        DestroyMenu(menuDisplayModes);
        menuDisplayModes = NULL;
    }

    return 0;
}
예제 #27
0
static LRESULT CALLBACK WndProc(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam) {
    switch (uMsg) {
        case WM_CREATE:
            break;
        case WM_PAINT: {
            PAINTSTRUCT ps;
            BeginPaint(hwnd,&ps);
            EndPaint(hwnd,&ps);

            if (ddsurfacePrimary == NULL) {
                unlock_bitmap();
                free_bitmap();
                free_dx_primary_surface();
                init_dx_primary_surface();

                RECT rct;
                GetClientRect(hwndMain,&rct);

                if (!init_bitmap(rct.right,rct.bottom))
                    fprintf(stderr,"WARNING WM_RESIZE init_bitmap(%u,%u) failed\n",
                            (unsigned int)rct.right,(unsigned int)rct.bottom);

                if (lock_bitmap()) {
                    render_pattern(dx_bitmap);
                    unlock_bitmap();
                }
            }

            update_screen();
            } break;
        case WM_DISPLAYCHANGE: {
            announce_fmt = true;

            unlock_bitmap();
            free_bitmap();
            free_dx_primary_surface();
            init_dx_primary_surface();

            RECT rct;
            GetClientRect(hwndMain,&rct);

            if (!init_bitmap(rct.right,rct.bottom))
                fprintf(stderr,"WARNING WM_RESIZE init_bitmap(%u,%u) failed\n",
                        (unsigned int)rct.right,(unsigned int)rct.bottom);

            if (lock_bitmap()) {
                render_pattern(dx_bitmap);
                unlock_bitmap();
            }

            InvalidateRect(hwndMain,NULL,FALSE); // DWM compositor-based versions set WM_PAINT such that only the affected area will repaint
            } return DefWindowProc(hwnd,uMsg,wParam,lParam);
        case WM_SIZE:
            if (!init_bitmap(LOWORD(lParam),HIWORD(lParam)))
                fprintf(stderr,"WARNING WM_RESIZE init_bitmap(%u,%u) failed\n",
                    LOWORD(lParam),HIWORD(lParam));

            if (lock_bitmap()) {
                render_pattern(dx_bitmap);
                unlock_bitmap();
            }

            InvalidateRect(hwndMain,NULL,FALSE); // DWM compositor-based versions set WM_PAINT such that only the affected area will repaint
            break;
        case WM_RBUTTONUP:
            populateDisplayModes();
            if (menuDisplayModes != NULL) {
                POINT pt;

                GetCursorPos(&pt);
                TrackPopupMenu(menuDisplayModes,TPM_LEFTALIGN|TPM_TOPALIGN|TPM_RIGHTBUTTON,pt.x,pt.y,0,hwnd,NULL);
            }
            break;
        case WM_COMMAND:
            if (wParam >= 4000 && wParam < (WPARAM)(4000+displayModesCount)) {
                DDSURFACEDESC devmode = displayModes[wParam-4000];
                HRESULT hr;

                fprintf(stderr,"Setting display to %u x %u x %ubpp\n",
                    (unsigned int)devmode.dwWidth,
                    (unsigned int)devmode.dwHeight,
                    (unsigned int)devmode.ddpfPixelFormat.dwRGBBitCount);
                if ((hr=ddraw->SetDisplayMode(devmode.dwWidth,devmode.dwHeight,devmode.ddpfPixelFormat.dwRGBBitCount,devmode.dwRefreshRate,0)) != DD_OK)
                    fprintf(stderr,"Failed to set display mode HR=0x%08lx\n",hr);
                if (hr == DDERR_NOEXCLUSIVEMODE) {
                    // NTS: Windows 95/98/ME DirectX demands we enter Exclusive cooperative mode before it allows mode changes that change bit depth
                    fprintf(stderr,"Sorry, Windows demands we set the cooperative mode to Exclusive\n"); // Windows 9x/ME behavior for NORMAL cooperative mode DirectX apps
                    try_exclusive_mode();
                    if ((hr=ddraw->SetDisplayMode(devmode.dwWidth,devmode.dwHeight,devmode.ddpfPixelFormat.dwRGBBitCount,devmode.dwRefreshRate,0)) != DD_OK)
                        fprintf(stderr,"Failed to set display mode HR=0x%08lx\n",hr);
                }

                if (hr == DD_OK) {
                    if (is_exclusive_mode()) {
                        // NTS: When we're in Exclusive Fullscreen mode, Windows doesn't broadcast WM_DISPLAYCHANGE or WM_PAINT the way it normally does while we're active.
                        //      So for our display code to work we have to poke and prod the window manager and make our window fullscreen, with focus.
                        unlock_bitmap();
                        free_bitmap();
                        free_dx_primary_surface();
                        init_dx_primary_surface();

                        RECT rct;
                        GetClientRect(hwndMain,&rct);

                        if (!init_bitmap(rct.right,rct.bottom))
                            fprintf(stderr,"WARNING WM_RESIZE init_bitmap(%u,%u) failed\n",
                                    (unsigned int)rct.right,(unsigned int)rct.bottom);

                        if (lock_bitmap()) {
                            render_pattern(dx_bitmap);
                            unlock_bitmap();
                        }

                        InvalidateRect(hwndMain,NULL,FALSE); // DWM compositor-based versions set WM_PAINT such that only the affected area will repaint
                        try_exclusive_mode();
                    }
                    hasSetMode = true;
                }
            }
            else if (wParam == 5000) {
                try_exclusive_mode();
                update_screen();
            }
            else if (wParam == 5001) {
                leave_exclusive_mode();
            }
            else if (wParam == 5002) {
                leave_exclusive_mode();
                ddraw->RestoreDisplayMode();
            }
            else {
                return DefWindowProc(hwnd,uMsg,wParam,lParam);
            }
            break;
        case WM_KEYDOWN:
            switch (wParam) {
                case VK_ESCAPE:
                    PostMessage(hwnd,WM_CLOSE,0,0);
                    break;
                case VK_SPACE:
                    if ((++pattern) >= 2)
                        pattern = 0;

                    if (lock_bitmap()) {
                        render_pattern(dx_bitmap);
                        unlock_bitmap();
                    }

                    InvalidateRect(hwndMain,NULL,FALSE); // DWM compositor-based versions set WM_PAINT such that only the affected area will repaint
                    break;
            }
            break;
        case WM_DESTROY:
            PostQuitMessage(0);
            break;
        default:
            return DefWindowProc(hwnd,uMsg,wParam,lParam);
    }

    return 0;
}
예제 #28
0
void update_screen() {
    IDirectDrawSurface *dst;
    RECT dstRect;
    RECT srcRect;
    HRESULT hr;
    POINT pt;

    // NTS: dx_bitmap.is_valid() is not a valid test because base==canvas==NULL unless surface is locked
    if (ddsurfaceBMP == NULL) return;

    // NTS: We must provide a source rect, else Windows XP in 24bpp mode will conveniently choose to render the
    //      right half (where extra padding+junk exist) rather than from the left side. Provide a source rect
    //      to make it 100% clear which part of the surface we want blitted to screen.
    pt.x = pt.y = 0;
    ClientToScreen(hwndMain,&pt);
    GetClientRect(hwndMain,&dstRect);
    OffsetRect(&dstRect,pt.x,pt.y);
    srcRect.top = srcRect.left = 0;
    srcRect.right = dx_bitmap.width;
    srcRect.bottom = dx_bitmap.height;

    if (ddsurfaceGDI != NULL)
        dst = ddsurfaceGDI;
    else if (ddsurfacePrimary != NULL)
        dst = ddsurfacePrimary;
    else
        dst = NULL;

    if (dst != NULL)
        hr = dst->Blt(&dstRect,ddsurfaceBMP,&srcRect,0,NULL);
    else
        hr = DD_OK;

    if (hr == DDERR_SURFACELOST) {
        fprintf(stderr,"Whoops, the primary surface was lost.\n");
        if ((hr=dst->Restore()) != DD_OK) {
            fprintf(stderr,"Unable to restore surface hr=0x%08lx.\n",hr);
            unlock_bitmap();
            free_bitmap();
            free_dx_primary_surface();
            init_dx_primary_surface();

            RECT rct;
            GetClientRect(hwndMain,&rct);

            if (!init_bitmap(rct.right,rct.bottom))
                fprintf(stderr,"WARNING WM_RESIZE init_bitmap(%u,%u) failed\n",
                        (unsigned int)rct.right,(unsigned int)rct.bottom);

            if (lock_bitmap()) {
                render_pattern(dx_bitmap);
                unlock_bitmap();
            }

            InvalidateRect(hwndMain,NULL,FALSE); // DWM compositor-based versions set WM_PAINT such that only the affected area will repaint
        }
    }
    else if (hr != DD_OK) {
        fprintf(stderr,"DirectX blit failed, HR=0x%08lx\n",hr);
    }
}
예제 #29
0
int init_bitmap(unsigned int w,unsigned int h,unsigned int align=32) {
    DDSURFACEDESC ddsurf,dispsurf;
    HRESULT hr;

    free_bitmap();
    if (w == 0 || h == 0) return 0;

    (void)align; // unused

    /* what screen format? we need to add padding to width just in case 24bpp */
    memset(&dispsurf,0,sizeof(dispsurf));
    dispsurf.dwSize = sizeof(dispsurf);
    if ((hr=ddraw->GetDisplayMode(&dispsurf)) != DD_OK) {
        fprintf(stderr,"Failed to query display mode HR=0x%08lx\n",hr);
        free_bitmap();
        return 0;
    }

    fprintf(stderr,"Screen is %u x %u x %ubpp\n",
        (unsigned int)dispsurf.dwWidth,
        (unsigned int)dispsurf.dwHeight,
        (unsigned int)dispsurf.ddpfPixelFormat.dwRGBBitCount);

    // NTS: We used to let DirectX auto-choose the primary surface depth for us, but... it turns out
    //      some versions of Windows have problems here when the screen has just changed bit depth.
    //      But GetDisplayMode() returns the new bit depth, so we can provide it anyway.
    //
    // Case 1: Windows XP: Changing from a higher to lower bit depth: CreateSurface with OFFSCREENPLAIN
    //         will make a surface with the stride and allocation of the new bit depth but the RGB bits
    //         per pixel of the old bit depth. Blind adherence to the bit depth will mean that we overrun
    //         the buffer, and crash.
    memset(&ddsurf,0,sizeof(ddsurf));
    ddsurf.dwSize = sizeof(ddsurf);
    ddsurf.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_PIXELFORMAT | DDSD_PITCH;
    ddsurf.ddpfPixelFormat = dispsurf.ddpfPixelFormat;
    ddsurf.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
    ddsurf.dwWidth = (w+3) & (~3); // NTS: Windows XP does weird things with 24bpp if width not a multiple of 4, including resetting lPitch to width * 3 ha ha!
    ddsurf.dwHeight = h;
    ddsurf.lPitch = ((ddsurf.ddpfPixelFormat.dwRGBBitCount+7)/8) * ddsurf.dwWidth;

    // DirectX demands at least DWORD alignment
    if (align < 4) align = 4;
    align = (align+3) & (~3); // round up

    /* if 24bpp, may need extra padding */
    if (ddsurf.ddpfPixelFormat.dwRGBBitCount == 24 && (w&3) == 0) {
        ddsurf.dwWidth += 4; // NTS: only because DirectX in Windows XP appears to ignore our pitch spec when creating the surface. Also width must be multiple of 4.
        ddsurf.lPitch = ((ddsurf.ddpfPixelFormat.dwRGBBitCount+7)/8) * ddsurf.dwWidth;
    }

    if (align > 0) {
        // try to encourage DirectX to set the pitch by our alignment.
        // Not that it works (from actual testing) but let's try anyway.
        ddsurf.lPitch += align - 1;
        ddsurf.lPitch -= ddsurf.lPitch % align;
    }

    hr = ddraw->CreateSurface(&ddsurf,&ddsurfaceBMP,NULL);
    if (hr == DDERR_INVALIDPARAMS && ddsurf.ddpfPixelFormat.dwRGBBitCount == 24) {
        // NTS: Apparently creating an offscreen surface wider than the screen is not supported by DirectX on Windows 95/98.
        //      We need the extra padding, so if we can't pad horizontally try padding vertically.
        fprintf(stderr,"Windows 9x/ME DirectX screen compenstation\n");

        ddsurf.dwHeight = h + 1;
        ddsurf.dwWidth = (w+3) & (~3); // NTS: Windows XP does weird things with 24bpp if width not a multiple of 4, including resetting lPitch to width * 3 ha ha!
        ddsurf.lPitch = ((ddsurf.ddpfPixelFormat.dwRGBBitCount+7)/8) * ddsurf.dwWidth;

        if (align > 0) {
            // try to encourage DirectX to set the pitch by our alignment.
            // Not that it works (from actual testing) but let's try anyway.
            ddsurf.lPitch += align - 1;
            ddsurf.lPitch -= ddsurf.lPitch % align;
        }

        hr = ddraw->CreateSurface(&ddsurf,&ddsurfaceBMP,NULL);
    }
    if (hr != DD_OK) {
        fprintf(stderr,"Failed to create BMP surface HR=0x%08lx\n",hr);
        free_bitmap();
        return 0;
    }

    memset(&ddsurf,0,sizeof(ddsurf));
    ddsurf.dwSize = sizeof(ddsurf);
    if ((hr=ddsurfaceBMP->GetSurfaceDesc(&ddsurf)) != DD_OK) {
        fprintf(stderr,"Failed to get BMP surface info HR=0x%08lx\n",hr);
        free_bitmap();
        return 0;
    }

    fprintf(stderr,"BMP surface info:");
    if ((ddsurf.dwFlags & (DDSD_WIDTH|DDSD_HEIGHT)) == (DDSD_WIDTH|DDSD_HEIGHT))
        fprintf(stderr," %lux%lu",(unsigned long)ddsurf.dwWidth,(unsigned long)ddsurf.dwHeight);
    if (ddsurf.dwFlags & DDSD_PITCH)
        fprintf(stderr," pitch=%lu",(unsigned long)ddsurf.lPitch);
    if (ddsurf.dwFlags & DDSD_PIXELFORMAT) {
        fprintf(stderr," pixelfmt=");
        if (ddsurf.ddpfPixelFormat.dwFlags & DDPF_RGB) {
            fprintf(stderr,"RGB=%ubpp ",(unsigned int)ddsurf.ddpfPixelFormat.dwRGBBitCount);
            fprintf(stderr,"R/G/B/A=0x%08lx/0x%08lx/0x%08lx/0x%08lx ",
                (unsigned long)ddsurf.ddpfPixelFormat.dwRBitMask,
                (unsigned long)ddsurf.ddpfPixelFormat.dwGBitMask,
                (unsigned long)ddsurf.ddpfPixelFormat.dwBBitMask,
                (unsigned long)ddsurf.ddpfPixelFormat.dwRGBAlphaBitMask);
        }
    }
    fprintf(stderr,"\n");

    {
        DWORD want = DDSD_WIDTH|DDSD_HEIGHT|DDSD_PITCH|DDSD_PIXELFORMAT;
        if ((ddsurf.dwFlags&want) != want) {
            fprintf(stderr,"DirectX did not provide sufficient information for me to work by\n");
            free_bitmap();
            return 0;
        }
    }

    if (!(ddsurf.ddpfPixelFormat.dwFlags & DDPF_RGB)) {
        fprintf(stderr,"DirectX did not provide pixel format or pixel format is not RGB\n");
        free_bitmap();
        return 0;
    }

    dx_bitmap.clear();
    dx_bitmap.width = w;
    dx_bitmap.height = h;
    dx_bitmap.bytes_per_pixel = (ddsurf.ddpfPixelFormat.dwRGBBitCount + 7) / 8;
    dx_bitmap.stride = ddsurf.lPitch;
    dx_bitmap.length = ddsurf.lPitch * ddsurf.dwHeight;

    dx_bitmap.rgbinfo.r.setByMask(ddsurf.ddpfPixelFormat.dwRBitMask);
    dx_bitmap.rgbinfo.g.setByMask(ddsurf.ddpfPixelFormat.dwGBitMask);
    dx_bitmap.rgbinfo.b.setByMask(ddsurf.ddpfPixelFormat.dwBBitMask);
    dx_bitmap.rgbinfo.a.setByMask(ddsurf.ddpfPixelFormat.dwRGBAlphaBitMask);

    // check!
    if (dx_bitmap.length < (dx_bitmap.height * dx_bitmap.stride)) {
        fprintf(stderr,"DirectX did not provide a surface with sufficient height\n");
        free_bitmap();
        return 0;
    }

    // 24bpp check: make sure the pitch (stride) is larger than width*3, or we were able to get at least one extra scanline
    if (ddsurf.ddpfPixelFormat.dwRGBBitCount == 24) {
        if (dx_bitmap.height == ddsurf.dwHeight) {
            if (dx_bitmap.stride <= (dx_bitmap.width*3)) {
                fprintf(stderr,"DirectX did not provide a surface with a stride padded enough for 24bpp\n");
                free_bitmap();
                return 0;
            }
        }
    }

    // check that we didn't catch DirectX mid-mode-change.
    // NTS: Apparently switching from 32bpp to 24bpp in Windows XP can cause an easily-hittable
    //      window of opportunity to create a primary surface with the stride of a 24bpp screen
    //      and the specification of a 32bpp screen. Needless to say, if we don't catch this,
    //      we will crash when we start to draw again.
    if ((dx_bitmap.width * dx_bitmap.bytes_per_pixel) > dx_bitmap.stride) {
        fprintf(stderr,"DirectX did not provide a valid surface pitch (Windows XP DirectX 24/32bpp mode change bug?)\n");
        free_bitmap();
        return 0;
    }

    // the catch with DirectX is that we cannot keep the pointer in the dx bitmap at all times,
    // because of the need to lock the surface. be aware of that. Until you lock the surface,
    // our dx_bitmap is technically invalid. I'm not going to just leave it locked because we
    // want DirectX to be able to Blit from our surface to the screen.
    dx_bitmap.base = dx_bitmap.canvas = NULL;

    return 1;
}