#include <stdio.h>
#include "XWDFile.h"


XWDColor *colorMap;
char *pixmap;
int width, height;

#define WHITE  1
#define RED    3
#define BLUE   0
#define GREEN 12
 
int readInt()
{
   int i, result;
   char *p = (char *)&result;
   for (i=0; i<4; i++) {
     *p++ = (char)getchar();
   }
   return result;
}

int readShort()
{
   int i;
   short result;
   char *p = (char *)&result;
   for (i=0; i<2; i++) {
     *p++ = (char)getchar();
   }
   return result;
}

void readHeader(XWDFileHeader *x)
{
   x->header_size = readInt();
   x->file_version = readInt();
   x->pixmap_format = readInt();
   x->pixmap_depth = readInt();
   x->pixmap_width = readInt();
   x->pixmap_height = readInt();
   x->xoffset = readInt();
   x->byte_order = readInt();
   x->bitmap_unit = readInt();
   x->bitmap_bit_order = readInt();
   x->bitmap_pad = readInt();
   x->bits_per_pixel = readInt();
   x->bytes_per_line = readInt();
   x->visual_class = readInt();
   x->red_mask = readInt();
   x->green_mask = readInt();
   x->blue_mask = readInt();
   x->bits_per_rgb = readInt();
   x->colormap_entries = readInt();
   x->ncolors = readInt();
   x->window_width = readInt();
   x->window_height = readInt();
   x->window_x = readInt();
   x->window_y = readInt();
   x->window_bdrwidth = readInt();
   x->header_end = readInt();
}

void printHeader(XWDFileHeader *x)
{
   printf("XWDFileHeader[\n");
   printf("\t header_size = %d\n", x->header_size);
   printf("\t file_version = %d\n", x->file_version);
   printf("\t pixmap_format = %d\n", x->pixmap_format);
   printf("\t pixmap_depth = %d\n", x->pixmap_depth);
   printf("\t pixmap_width = %d\n", x->pixmap_width);
   printf("\t pixmap_height = %d\n", x->pixmap_height);
   printf("\t xoffset = %d\n", x->xoffset);
   printf("\t byte_order = %d\n", x->byte_order);
   printf("\t bitmap_unit = %d\n", x->bitmap_unit);
   printf("\t bitmap_bit_order = %d\n", x->bitmap_bit_order);
   printf("\t bitmap_pad = %d\n", x->bitmap_pad);
   printf("\t bits_per_pixel = %d\n", x->bits_per_pixel);
   printf("\t bytes_per_line = %d\n", x->bytes_per_line);
   printf("\t visual_class = %d\n", x->visual_class);
   printf("\t red_mask = %d\n", x->red_mask);
   printf("\t green_mask = %d\n", x->green_mask);
   printf("\t blue_mask = %d\n", x->blue_mask);
   printf("\t bits_per_rgb = %d\n", x->bits_per_rgb);
   printf("\t colormap_entries = %d\n", x->colormap_entries);
   printf("\t ncolors = %d\n", x->ncolors);
   printf("\t window_width = %d\n", x->window_width);
   printf("\t window_height = %d\n", x->window_height);
   printf("\t window_x = %d\n", x->window_x);
   printf("\t window_y = %d\n", x->window_y);
   printf("\t window_bdr_width = %d\n", x->window_bdrwidth);
   printf("\t header_end = %d\n", x-> header_end);
   printf("]\n");
}

void printShortHeader(XWDFileHeader *x)
{
   printf("XWDFileHeader[");
   printf("version = %d, ", x->file_version);
   printf("width = %d, ", x->pixmap_width);
   printf("height = %d, ", x->pixmap_height);
   printf("nentries = %d, ", x->colormap_entries);
   printf("ncolors = %d, ", x->ncolors);
   printf("x = %d, ", x->window_x);
   printf("y = %d, ", x->window_y);
   printf("]\n");
}

void outputHeader(XWDFileHeader *x)
{
   int i, r;
   char *p = (char*)x;
   for (i=0; i<x->header_size; i++) {
     r = putchar(*p++);
   }
}

void readEntry(XWDColor *x)
{
   x->pixel = readInt();
   x->red = readShort();
   x->green = readShort();
   x->blue = readShort();
   x->flags = (char)getchar();
   x->pad = (char)getchar();
}

void copyEntry(XWDColor *x, XWDColor *y)
{
   y->pixel = x->pixel;
   y->red = x->red;
   y->green = x->green;
   y->blue = x->blue;
   y->flags = x->flags;
   y->pad = x->pad;
}

void printEntry(XWDColor *x)
{
   printf("XColorMapEntry[");
   printf("%d, ", x->pixel);
   printf("red = %hx, ", x->red);
   printf("green = %hx, ", x->green);
   printf("blue = %hx, ", x->blue);
   printf("flags = %xh]\n", x->flags);
}

void outputEntry(XWDColor *x)
{
   int i, r;
   char *p = (char*)x;
   for (i=0; i<sizeof(XWDColor); i++) {
     r = putchar(*p++);
   }
}


/*  YOU WRITE THIS SUBROUTINE:    */

void processImage(char *pixMap, int width, int height)
{
   /*   pixMap   = %o0
        width    = %o1
        height   = %o2
   */

   /*  ASM statements go here:  */

    /*    int i, j, k;
    
	  for (k=0; k<3; k++)
	  for (i=0; i<height; i++) 
	  for (j=0; j<width-2; j++) 
	  if ((pixMap[i*width+j]==BLUE)&&
	  (pixMap[i*width+j+1]==BLUE)&&
	  (pixMap[i*width+j+2]==WHITE)) {
	  pixMap[i*width+j+1]=WHITE;
	  }
	  */

    asm("	");  /*  Terminators */
    asm("	mov	%i1, %l5	 ");  /*  terminator for j */
    asm("	sub	%l5, 0x2, %l5");
    asm("	mov	%i2, %l6	 ");  /*  terminator for i */
    asm("	");
    asm("	mov	0x0, %l0	 ");  /*  k */
    asm("k_loop:");
    asm("	mov	0x0, %l1	 ");  /*  i */
    asm("i_loop:");
    asm("	mov	0x0, %l2	 ");  /*  j */
    asm("j_loop:	");
    asm("       mov     0x0, %l3");
    asm("	umul	%l1, %i1, %l3");
    asm("	add	%l3, %l2, %l3");
    asm("       ldub     [%i0 + %l3], %g1");
    asm("       mov     0x0, %l4");
    asm("	cmp	%g1, %l4");
    asm("	bnz	loop");
    asm("	nop");
    asm("	inc	%l3");
    asm("       ldub     [%i0 + %l3], %g1");
    asm("       mov     0x0, %l4");
    asm("	cmp	%g1, %l4");
    asm("	bnz	loop");
    asm("	nop");
    asm("	inc	%l3");
    asm("       ldub     [%i0 + %l3], %g1");
    asm("       mov     0x1, %l4");
    asm("	cmp	%g1, %l4");
    asm("	bnz	loop");
    asm("	nop");
    asm("	sub	%l3, 0x1, %l3");
    asm("       mov     0x1, %l4");
    asm("	stb	%l4, [%i0 + %l3]");
    asm("loop:");
    asm("	inc	%l2");
    asm("	cmp	%l2, %l5");
    asm("	bl	j_loop");
    asm("	nop");
    asm("	inc	%l1");
    asm("	cmp	%l1, %l6");
    asm("	bl	i_loop");
    asm("	nop");
    asm("	inc	%l0");
    asm("	cmp	%l0, 0x3");
    asm("	bl	k_loop");
    asm("	nop"); 

    return;    
}


void main(int argv, char* args[])
{
   int i, j, r;

   XWDFileHeader *header =
     (XWDFileHeader*)malloc(sizeof(XWDFileHeader));
   XWDColor *entry =
     (XWDColor*)malloc(sizeof(XWDColor));

   /* this code is here only to locate these variables: */
   pixmap   = (char*)10;
   colorMap = (XWDColor*)20;

   /* copy the XWD fileheader */
   readHeader(header);
   outputHeader(header);

   fseek(stdin, header->header_size, 0);

   /* load and copy the color map */
   colorMap =
     (XWDColor*)malloc(sizeof(XWDColor)*(header->colormap_entries));
   for (i=0; i<header->colormap_entries; i++) {
     readEntry(entry);
     copyEntry(entry, &colorMap[i]);
     outputEntry(entry);
   }

   /*  allocate the pixmap */
   width = header->pixmap_width;
   height = header->pixmap_height;
   pixmap = (char*)malloc(width*height);

   j = 0;
   while (1) {
     if (feof(stdin)) break;
     pixmap[j++] = (char)getchar();
   }


   /****************************************************************/

   processImage(pixmap, width, height);      /* You write this one */

   /****************************************************************/

   /* write the pixmap */
   for (i=0; i<width*height; i++) {
     r = putchar(pixmap[i]);
   }

}

