
#include <stdio.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/time.h>
#include <sys/ioctl.h>
#include <dev/wscons/wsconsio.h>


#include "srl.h"
#include "mjpeg_tasks.h"

#include "jpeg_data.h"
#include "jpeg.h"

static uint32_t chksum = 0;

static void *fb = NULL;
static struct wsdisplay_fbinfo ws_fbinfo;
static uint fb_stride;

void ramdac_func_bootstrap(struct _ramdac_args_t *_func_args)
{
	if (fb_file >= 0) {
		int m, m2;
		if (ioctl(fb_file, WSDISPLAYIO_GINFO, &ws_fbinfo) < 0) {
			perror("WSDISPLAYIO_GINFO");
			exit(1);
		}
		if (ioctl(fb_file, WSDISPLAYIO_LINEBYTES, &fb_stride) < 0) {
			perror("WSDISPLAYIO_LINEBYTES");
			exit(1);
		}
		if (ioctl(fb_file, WSDISPLAYIO_GMODE, &m) < 0) {
			perror("WSDISPLAYIO_GMODE");
			exit(1);
		}
		m2 = WSDISPLAYIO_MODE_DUMBFB;
		if (ioctl(fb_file, WSDISPLAYIO_SMODE, &m2) < 0) {
			perror("WSDISPLAYIO_SMODE");
			exit(1);
		}
		printf("using framebuffer %dx%d (line size %d) %dbpp ",
		    ws_fbinfo.width, ws_fbinfo.height, fb_stride,
		    ws_fbinfo.depth);
		fb = mmap(NULL, ws_fbinfo.height * fb_stride,
		    PROT_READ|PROT_WRITE, MAP_FILE,
		    fb_file, 0);
		if (fb == MAP_FAILED) {
			perror("can't mmap framebuffer");
			if (ioctl(fb_file, WSDISPLAYIO_SMODE, &m) < 0) {
				perror("WSDISPLAYIO_SMODE");
				exit(1);
			}
			exit(1);
		}
		printf("mapped at %p\n", fb);
	}
}

void ramdac_func_ramdac(struct _ramdac_args_t *_func_args)
{
  srl_mwmr_t input = _func_args->input;
  int32_t i, j;

  for (i = 0; i < MAX_HEIGHT; i += 8) {
    uint8_t row[MAX_WIDTH * 8];

    srl_mwmr_read( input, row, 8 * MAX_WIDTH );
    if (verbose) {
	    for (j = 0; j < MAX_WIDTH * 8; j++)
	      chksum = (chksum << 1) + row[j];
    }
    if (fb != NULL) {
	void *fbline;
	int k;
	for (k = 0; k < 8; k++) {
		fbline = (void *)((char *)fb + ((i + k) * fb_stride));
		if (ws_fbinfo.depth == 8)
			memcpy(fbline, &row[k*MAX_WIDTH], MAX_WIDTH);
		else for (j = 0; j < MAX_WIDTH; j++) {
			switch (ws_fbinfo.depth) {
			case 15:
				((uint16_t *)fbline)[j] = 
				    (row[k*MAX_WIDTH+j] >> 3) << 10 |
				    (row[k*MAX_WIDTH+j] >> 3) <<  5 |
				    (row[k*MAX_WIDTH+j] >> 3);
				break;
			case 16:
				((uint16_t *)fbline)[j] = 
				    (row[k*MAX_WIDTH+j] >> 3) << 11 |
				    (row[k*MAX_WIDTH+j] >> 2) <<  5 |
				    (row[k*MAX_WIDTH+j] >> 3);
				break;
			case 32:
				((uint32_t *)fbline)[j] = 
				    row[k*MAX_WIDTH+j] << 16 |
				    row[k*MAX_WIDTH+j] <<  8 |
				    row[k*MAX_WIDTH+j];
				break;
				
			default:
				fprintf(stderr, "unsupported depth %d\n",
				    ws_fbinfo.depth);
				exit(1);
			}
		}
	}
    }
  }

  if (verbose)
	  printf("Image sum: %08x\n", chksum);
}

