static void game_compute_size(const game_params *params, int tilesize, int *x, int *y) { struct bbox bb = find_bbox(params); *x = XSIZE(tilesize, bb, solids[params->solid]); *y = YSIZE(tilesize, bb, solids[params->solid]); }
static void game_set_size(drawing *dr, game_drawstate *ds, const game_params *params, int tilesize) { struct bbox bb = find_bbox(params); ds->gridscale = (float)tilesize; ds->ox = (int)(-(bb.l - solids[params->solid]->border) * ds->gridscale); ds->oy = (int)(-(bb.u - solids[params->solid]->border) * ds->gridscale); }
static void game_redraw(drawing *dr, game_drawstate *ds, const game_state *oldstate, const game_state *state, int dir, const game_ui *ui, float animtime, float flashtime) { int i, j; struct bbox bb = find_bbox(&state->params); struct solid *poly; const int *pkey, *gkey; float t[3]; float angle; int square; draw_rect(dr, 0, 0, XSIZE(GRID_SCALE, bb, state->solid), YSIZE(GRID_SCALE, bb, state->solid), COL_BACKGROUND); if (dir < 0) { const game_state *t; /* * This is an Undo. So reverse the order of the states, and * run the roll timer backwards. */ assert(oldstate); t = oldstate; oldstate = state; state = t; animtime = ROLLTIME - animtime; } if (!oldstate) { oldstate = state; angle = 0.0; square = state->current; pkey = state->dpkey; gkey = state->dgkey; } else { angle = state->angle * animtime / ROLLTIME; square = state->previous; pkey = state->spkey; gkey = state->sgkey; } state = oldstate; for (i = 0; i < state->grid->nsquares; i++) { int coords[8]; for (j = 0; j < state->grid->squares[i].npoints; j++) { coords[2*j] = ((int)(state->grid->squares[i].points[2*j] * GRID_SCALE) + ds->ox); coords[2*j+1] = ((int)(state->grid->squares[i].points[2*j+1]*GRID_SCALE) + ds->oy); } draw_polygon(dr, coords, state->grid->squares[i].npoints, GET_SQUARE(state, i) ? COL_BLUE : COL_BACKGROUND, COL_BORDER); } /* * Now compute and draw the polyhedron. */ poly = transform_poly(state->solid, state->grid->squares[square].flip, pkey[0], pkey[1], angle); /* * Compute the translation required to align the two key points * on the polyhedron with the same key points on the current * face. */ for (i = 0; i < 3; i++) { float tc = 0.0; for (j = 0; j < 2; j++) { float grid_coord; if (i < 2) { grid_coord = state->grid->squares[square].points[gkey[j]*2+i]; } else { grid_coord = 0.0; } tc += (grid_coord - poly->vertices[pkey[j]*3+i]); } t[i] = tc / 2; } for (i = 0; i < poly->nvertices; i++) for (j = 0; j < 3; j++) poly->vertices[i*3+j] += t[j]; /* * Now actually draw each face. */ for (i = 0; i < poly->nfaces; i++) { float points[8]; int coords[8]; for (j = 0; j < poly->order; j++) { int f = poly->faces[i*poly->order + j]; points[j*2] = (poly->vertices[f*3+0] - poly->vertices[f*3+2] * poly->shear); points[j*2+1] = (poly->vertices[f*3+1] - poly->vertices[f*3+2] * poly->shear); } for (j = 0; j < poly->order; j++) { coords[j*2] = (int)floor(points[j*2] * GRID_SCALE) + ds->ox; coords[j*2+1] = (int)floor(points[j*2+1] * GRID_SCALE) + ds->oy; } /* * Find out whether these points are in a clockwise or * anticlockwise arrangement. If the latter, discard the * face because it's facing away from the viewer. * * This would involve fiddly winding-number stuff for a * general polygon, but for the simple parallelograms we'll * be seeing here, all we have to do is check whether the * corners turn right or left. So we'll take the vector * from point 0 to point 1, turn it right 90 degrees, * and check the sign of the dot product with that and the * next vector (point 1 to point 2). */ { float v1x = points[2]-points[0]; float v1y = points[3]-points[1]; float v2x = points[4]-points[2]; float v2y = points[5]-points[3]; float dp = v1x * v2y - v1y * v2x; if (dp <= 0) continue; } draw_polygon(dr, coords, poly->order, state->facecolours[i] ? COL_BLUE : COL_BACKGROUND, COL_BORDER); } sfree(poly); draw_update(dr, 0, 0, XSIZE(GRID_SCALE, bb, state->solid), YSIZE(GRID_SCALE, bb, state->solid)); /* * Update the status bar. */ { char statusbuf[256]; if (state->completed) { strcpy(statusbuf, _("COMPLETED!")); strcpy(statusbuf+strlen(statusbuf), " "); } else statusbuf[0] = '\0'; sprintf(statusbuf+strlen(statusbuf), _("Moves: %d"), (state->completed ? state->completed : state->movecount)); status_bar(dr, statusbuf); } }
main(int argc, char* argv[]) { //START; // the required page number in a multipage tiff, use 0 for first page int dir_num; dir_num = atoi(argv[2]); //time_t start, end; double duration; TIFF* tif = TIFFOpen(argv[1], "r"); //get number of pages (Directories) in a tiff file int dir_count; dir_count = TIFFNumberOfDirectories(tif); if(dir_num < 0 || dir_num > (dir_count-1)){ printf("Error: invalid directory number\n"); exit -1; } else{ if (tif) { uint32 w, h; size_t npixels; uint32* raster; // set the required page (directory) // change to the requested directory and read its contents with TIFFReadDirectory TIFFSetDirectory(tif,dir_num); TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &w); TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &h); npixels = w * h; int r,v; //Foreground and Background pixel values int F = 1, B = 0; size_t c_h, c_w; raster = (uint32*) _TIFFmalloc(npixels * sizeof (uint32)); // image matrix with added boundary pixels int** I = malloc((h+2) * sizeof(int*)); // allocate the rows for ( r = 0; r < (h+2); ++r) { I[r] = malloc((w+2) * sizeof(int)); // allocate the columns //for ( cx = 0; cx < COLS; ++cx) // I[r][cx] = 0; } // an array of pixel runs (hashtable of pixel runs) // each run is a linked list of pixels struct pixel **runs = malloc((h*w/4) * sizeof(struct pixel)); //initialise arrays and linked list for ( v = 0; v < (h*w/4); ++v) { //C[r] = r; // initialise labels init_pixel(runs[v], 99,99); } // arrays to save classes and their mappings //uint32* C = malloc((ROWS*COLS/2) * sizeof(uint32*)); uint32* rl_table = malloc((h*w/4) * sizeof(uint32*)); uint32* n_label = malloc((h*w/4) * sizeof(uint32*)); uint32* t_label = malloc((h*w/4) * sizeof(uint32*)); for ( v = 0; v < (h*w/4); ++v) { //C[r] = r; // initialise classes rl_table[v] = v; n_label[v] = -1; t_label[v] = v; } // load image into matrix of F and B pixels (1's and 0's) if (raster != NULL) { if (TIFFReadRGBAImage(tif, w, h, raster, 0)) { for(c_h=0;c_h<h;c_h++) { for(c_w=0;c_w<w;c_w++) { v = raster[(w*h)-((c_h*w)+(w-c_w))]%256; if (v == 0) I[c_h+1][c_w+1] = F; else I[c_h+1][c_w+1] = B; } } } _TIFFfree(raster); } /* c2 c3 c4 c1 x */ // FIRST SCAN int i,j,k; int NewLabel=5; int c1,c2,c3,c4,uu,vv,ii; for(c_h=1;c_h<(h-1);c_h++) for(c_w=1;c_w<(w-1);c_w++){ // for COLS if (I[c_h][c_w] == F) { c3 = I[c_h-1][c_w] ; if (c3 != B) { I[c_h][c_w] = c3; } else // else1 { c4 = I[c_h-1][c_w+1] ; c1 = I[c_h][c_w-1] ; if (c1 != B) { I[c_h][c_w] = c1; if (c4 != B && c4 != c1) { //printf ("(%d,%d);", c1, c4); //(* resolve c2 c4 *) uu = rl_table[c1]; vv = rl_table[c4]; if(uu<vv){ ii = vv; while(ii != -1){ rl_table[ii] = uu; ii = n_label[ii]; } n_label[t_label[uu]] = vv; t_label[uu] = t_label[vv]; } else{ if(vv<uu){ ii = uu; while(ii != -1){ rl_table[ii] = vv; ii = n_label[ii]; } n_label[t_label[vv]] = uu; t_label[vv] = t_label[uu]; } } } } else // else2 { c2 = I[c_h-1][c_w-1] ; if (c2 != B) { I[c_h][c_w] = c2; if (c4 != B && c4 != c2) { //printf("(%d,%d);\n", c2, c4); //(* resolve c2 c4 *) uu = rl_table[c2]; vv = rl_table[c4]; if(uu<vv){ ii = vv; while(ii != -1){ rl_table[ii] = uu; ii = n_label[ii]; } n_label[t_label[uu]] = vv; t_label[uu] = t_label[vv]; } else{ if(vv<uu){ ii = uu; while(ii != -1){ rl_table[ii] = vv; ii = n_label[ii]; } n_label[t_label[vv]] = uu; t_label[vv] = t_label[uu]; } } } } else if (c4 != B) { I[c_h][c_w] = c4; } else { I[c_h][c_w] = NewLabel; NewLabel=NewLabel+1; } }// else2 }// else1 } } // end for COLS // SECOND SCAN for(c_h=0;c_h<h;c_h++) for(c_w=0;c_w<w;c_w++) // for COLS if (I[c_h][c_w] != B) I[c_h][c_w] = rl_table[I[c_h][c_w]]; //get linked lists of pixels with the same class //i.e. pixels that belong to the same CC for(c_h=0;c_h<h;c_h++){ for(c_w=0;c_w<w;c_w++){ if (I[c_h][c_w] != B) { push(&runs[I[c_h][c_w]], c_w,c_h); } } } //now open a file, find coords of each CC and save them // char *base = get_basename(argv[1]);// = "filename"; char *base = argv[1]; // find location of last '.' in filename to chop extension char *pos = strrchr (base, '.'); int pos1 = pos ? (pos - base ) : -1; if(pos1 != -1){ base[pos1] = 0; // remove file extension //printf("%d, %s\n",pos1, base); } //I'm assuming length of filename doesn't exceed 50 chars //I'll deal with this later char filename[256]; FILE *file; //fname1[strlen(fname1) - 4] = 0; // remove file extension sprintf(filename, "%s-%d.json", base, dir_num); //printf("%s\n", filename); file = fopen(filename,"w+"); fprintf(file,"{\n"); fprintf(file," \"SrcImage\": \"\",\n"); fprintf(file," \"Page\": %d,\n",dir_num); fprintf(file," \"PageWidth\": %d,\n", w); fprintf(file," \"PageHeight\": %d,\n",h); fprintf(file," \"ClipX\": %d,\n",0); fprintf(file," \"ClipY\": %d,\n",0); fprintf(file," \"ClipWidth\": %d,\n", w); fprintf(file," \"ClipHeight\": %d,\n",h); fprintf(file," \"ClipImage\": \"\",\n"); fprintf(file," \"glyphs\": [\n"); //count++; //file = fopen("file.txt","w+"); int len; for ( v = 0; v < (h*w/4); ++v) { len = length(runs[v]); if (len > 0 ){ //printf("run ID: %d, run length %d\n", r, len ); struct bbox* b = find_bbox (runs[v]); //printf("bbox: (%d,%d),(%d,%d)\n", b->x1, b->y1, b->x2, b->y2 ); fprintf(file," { \"x\" : %d, \"y\" : %d, \"w\" : %d, \"h\" : %d }",(b->x1-1),(b->y1-1), (b->x2 - b->x1 + 1), (b->y2 - b->y1 + 1)); fprintf(file, ",\n"); free(runs[v]);// = NULL; free(b); } } // trick by Volker to remove comma after last glyph fseek(file, -( 2*(int)sizeof(char) ), SEEK_CUR); fprintf(file,"\n ]\n"); fprintf(file,"}\n"); // close file fclose(file); //printf("Generated: %s\n",filename); //manually free space allocated to various arrays and matrices for (v = 0; v < h; ++v) { free(I[v]); // this frees the columns } free(I); // this frees the rows free(runs); //free(C); free(rl_table); free(n_label); free(t_label); TIFFClose(tif); }//end if tif } //end else //STOP; //PRINTTIME; }