void free_rotate (ppm_t *p, double amount) { int x, y; double nx, ny; ppm_t tmp = {0, 0, NULL}; double f = amount * G_PI * 2 / 360.0; int rowstride = p->width * 3; ppm_new (&tmp, p->width, p->height); for (y = 0; y < p->height; y++) { for (x = 0; x < p->width; x++) { double r, d; nx = fabs (x - p->width / 2.0); ny = fabs (y - p->height / 2.0); r = sqrt (nx * nx + ny * ny); d = atan2 ((y - p->height / 2.0), (x - p->width / 2.0)); nx = (p->width / 2.0 + cos (d - f) * r); ny = (p->height / 2.0 + sin (d - f) * r); get_rgb (p, nx, ny, tmp.col + y * rowstride + x * 3); } } ppm_kill (p); p->width = tmp.width; p->height = tmp.height; p->col = tmp.col; }
void create_image_ppm(uint32_t *pic, int32_t size_x, int32_t size_y, char *filename) { //ouverture du fichier et ecriture de l'entete FILE *file = fopen(filename, "wb"); fprintf(file, "P6\n%d %d\n255\n", size_x, size_y); unsigned char color[3]; //ecriture de chaque pixel de picture for (int32_t i = 0; i < size_x * size_y; i++) { get_rgb(pic[i], color); fwrite(color, 1, 3, file); } //fermeture du fichier fclose(file); }
void make_pillar(char *prefix, int ix, int iy, fastf_t *center, fastf_t *lwh, struct wmember *headp) /* center of base */ { vect_t min, max; unsigned char rgb[4]; /* needs all 4 */ char pilname[32], rname[32], sname[32], oname[32]; int i; struct wmember head; struct wmember *wp; BU_LIST_INIT( &head.l ); snprintf( pilname, 32, "%s%d,%d", prefix, ix, iy ); snprintf( rname, 32, "%s.r", pilname ); snprintf( sname, 32, "%s.s", pilname ); snprintf( oname, 32, "Obj%d,%d", ix, iy ); VMOVE( min, center ); min[X] -= lwh[X]; min[Y] -= lwh[Y]; VADD2( max, center, lwh ); mk_rpp( outfp, sname, min, max ); /* Needs to be in a region, with color! */ get_rgb(rgb); i = PICK_MAT; mk_region1( outfp, rname, sname, mtab[i].mt_name, mtab[i].mt_param, rgb ); (void)mk_addmember( rname, &head.l, NULL, WMOP_UNION ); wp = mk_addmember( oname, &head.l, NULL, WMOP_UNION ); MAT_DELTAS( wp->wm_mat, center[X], center[Y], center[Z]+lwh[Z] ); mk_lfcomb( outfp, pilname, &head, 0 ); (void)mk_addmember( pilname, &(headp->l), NULL, WMOP_UNION ); }
void resize (ppm_t *p, int nx, int ny) { int x, y; float xs = p->width / (float)nx; float ys = p->height / (float)ny; ppm_t tmp = {0, 0, NULL}; ppm_new (&tmp, nx, ny); for (y = 0; y < ny; y++) { guchar *row = tmp.col + y * tmp.width * 3; for (x = 0; x < nx; x++) { get_rgb (p, x * xs, y * ys, &row[x * 3]); } } ppm_kill (p); p->width = tmp.width; p->height = tmp.height; p->col = tmp.col; }
/* The main drawing function. */ void DrawGLScene(){ glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); glLoadIdentity(); double RotationAngleX = 0.0; double RotationAngleY = 0.0; double RotationAngleZ = 0.0; if( dim3d==1 ) RotationAngleX = -60.0; if( dim3d==2 ) RotationAngleX = -90.0; glTranslatef( 0.0 , 0.0 , -CAM_BACKUP ); glRotatef(RotationAngleX, 1, 0, 0); glRotatef(RotationAngleY, 0, 1, 0); glRotatef(RotationAngleZ, 0, 0, 1); int q = valq; getMaxMin(); if( print_vals==0 ){ printf("Max = %e Min = %e\n",maxval,minval); print_vals=1; } double camdist = 0.0;//-CAM_BACKUP; double xoff = offx; double yoff = offy; double zoff = 0.0; if( draw_1d ){ glColor3f(1.0,1.0,1.0); glBegin(GL_QUADS); glVertex3f(-1./rescale-xoff,-1./rescale-yoff, camdist + zoff ); glVertex3f( 1./rescale-xoff,-1./rescale-yoff, camdist + zoff ); glVertex3f( 1./rescale-xoff, 1./rescale-yoff, camdist + zoff ); glVertex3f(-1./rescale-xoff, 1./rescale-yoff, camdist + zoff ); glEnd(); glLineWidth( 3.0f ); glColor3f(0.0,0.0,0.0); glBegin( GL_LINE_STRIP ); int j; // for( j=0 ; j<Nr ; ++j ){ for( j=0 ; j<Nr ; ++j ){ //if(logscale) val = log(getval(theZones[i],q))/log(10.); double rm = r_jph[j-1]; double rp = r_jph[j]; double val = theRadialData[j][q]/max_1d;//*pow(.5*(rp+rm),1.5);//2.*(theRadialData[j][q]-minval)/(maxval-minval) - 1.;//getval(theZones[i],q); if( q==1 ) val *= 1e2; val = 2.*val - 1.; double c0 = 2.*((.5*(rp+rm)-r_jph[-1])/(r_jph[Nr-1]-r_jph[-1]) - .5)/rescale; double c1 = val/rescale; glVertex3f( c0-xoff, c1-yoff, camdist-zoff+.001 ); } glEnd(); /* glColor3f(0.5,0.5,0.5); glBegin( GL_LINE_STRIP ); for( j=0 ; j<Nr ; ++j ){ //if(logscale) val = log(getval(theZones[i],q))/log(10.); double rm = r_jph[j-1]; double rp = r_jph[j]; double r = .5*(rp+rm); double val = pow(r,-1.5)/max_1d;// *pow(.5*(rp+rm),1.5);//2.*(theRadialData[j][q]-minval)/(maxval-minval) - 1.;//getval(theZones[i],q); if( q==1 ) val *= 1e2; val = 2.*val - 1.; double c0 = 2.*((.5*(rp+rm)-r_jph[-1])/(r_jph[Nr-1]-r_jph[-1]) - .5)/rescale; double c1 = val/rescale; glVertex3f( c0-xoff, c1-yoff, camdist-zoff+.001 ); } glEnd(); */ if( draw_planet ){ double eps = 0.01; int p; for( p=0 ; p<Npl ; ++p ){ double r = thePlanets[p][0]; double x = 2.*(( r - r_jph[-1] )/( r_jph[Nr-1]-r_jph[-1] ) - .5)/rescale; glColor3f(0.0,0.0,0.0); glLineWidth(2.0); glBegin(GL_LINE_LOOP); glVertex3f( x-xoff+eps , 1./rescale-yoff+eps , camdist+.001 ); glVertex3f( x-xoff-eps , 1./rescale-yoff+eps , camdist+.001 ); glVertex3f( x-xoff-eps , 1./rescale-yoff-eps , camdist+.001 ); glVertex3f( x-xoff+eps , 1./rescale-yoff-eps , camdist+.001 ); glEnd(); } } }else{ int Num_Draws = 1+reflect+draw_border; int count; int i,j; for( count = 0 ; count < Num_Draws ; ++count ){ int draw_border_now = 0; int draw_reflected_now = 0; if( count==reflect+1 ) draw_border_now = 1; if( reflect && count==1 ) draw_reflected_now = 1; if( draw_border_now ) zoff -= .0001; for( j=0 ; j<Nr ; ++j ){ double rm = r_jph[j-1]/rescale; double rp = r_jph[j]/rescale; double rc = .5*(rp+rm); double dr = rp-rm; if( !draw_border ){ rm = rc-.55*dr; rp = rc+.55*dr; } for( i=0 ; i<Np[j] ; ++i ){ double phip = p_iph[j][i]; double phim; if( i==0 ) phim = p_iph[j][Np[j]-1]; else phim = p_iph[j][i-1]; if( t_off && !p_off ){ phip -= t; phim -= t; } if( p_off ){ phip -= thePlanets[1][1]; phim -= thePlanets[1][1]; } double dp = phip-phim; while( dp < 0.0 ) dp += 2.*M_PI; while( dp > 2.*M_PI ) dp -= 2.*M_PI; double phi = phim + 0.5*dp; if( !draw_border ){ phip = phi+.55*dp; phim = phi-.55*dp; } double val = (getval(theZones[j][i],q)-minval)/(maxval-minval); if(logscale) val = (log(getval(theZones[j][i],q))/log(10.)-minval)/(maxval-minval); if( val > 1.0 ) val = 1.0; if( val < 0.0 ) val = 0.0; //double u = getval( theZones[j][i] , 2 ); //if( uMax < u ) uMax = u; float rrr,ggg,bbb; get_rgb( val , &rrr , &ggg , &bbb , cmap ); //if( (!dim3d || (sin(phi)>0 || cos(phi+.25)<0.0)) && dim3d !=2 ){ if( dp < 1.5 && (!dim3d || (sin(phi)>0 && cos(phi)>0.0)) && dim3d !=2 ){ if( !draw_border_now ){ glColor3f( rrr , ggg , bbb ); glBegin(GL_POLYGON); }else{ glLineWidth(3.0f); glColor3f(0.0,0.0,0.0); glBegin(GL_LINE_LOOP); } double z0 = 0.0; if( dim3d ) z0 = z_kph[Nz-1]/rescale; double c0 = rm*cos(phim); double c1 = rm*sin(phim); glVertex3f( c0-xoff, c1-yoff, camdist-zoff+z0 ); c0 = rp*cos(phim); c1 = rp*sin(phim); glVertex3f( c0-xoff, c1-yoff, camdist-zoff+z0 ); c0 = rp*cos(phi)/cos(.5*dp); c1 = rp*sin(phi)/cos(.5*dp); glVertex3f( c0-xoff, c1-yoff, camdist-zoff+z0 ); c0 = rp*cos(phip); c1 = rp*sin(phip); glVertex3f( c0-xoff, c1-yoff, camdist-zoff+z0 ); c0 = rm*cos(phip); c1 = rm*sin(phip); glVertex3f( c0-xoff, c1-yoff, camdist-zoff+z0 ); glEnd(); } } if( dim3d ){ int k; for( k=0 ; k<Nz ; ++k ){ int jk = j*Nz+k; double rp = r_jph[j]/rescale; double rm = r_jph[j-1]/rescale; double zp = z_kph[k]/rescale; double zm = z_kph[k-1]/rescale; double phi = 0.0;//rzZones[jk][Nq]; double val = (getval(rzZones[jk],q)-minval)/(maxval-minval); if(logscale) val = (log(getval(rzZones[jk],q))/log(10.)-minval)/(maxval-minval); if( val > 1.0 ) val = 1.0; if( val < 0.0 ) val = 0.0; float rrr,ggg,bbb; get_rgb( val , &rrr , &ggg , &bbb , cmap ); if( !draw_border_now ){ glColor3f( rrr , ggg , bbb ); glBegin(GL_POLYGON); }else{ glLineWidth(2.0f); glColor3f(0.0,0.0,0.0); glBegin(GL_LINE_LOOP); } glVertex3f( rp*cos(phi) - xoff , rp*sin(phi) - yoff + zoff, zp ); glVertex3f( rm*cos(phi) - xoff , rm*sin(phi) - yoff + zoff, zp ); glVertex3f( rm*cos(phi) - xoff , rm*sin(phi) - yoff + zoff, zm ); glVertex3f( rp*cos(phi) - xoff , rp*sin(phi) - yoff + zoff, zm ); glEnd(); } if( draw_border_now || dim3d == 1 ){ glLineWidth(2.0f); glColor3f(0.0,0.0,0.0); glBegin(GL_LINE_LOOP); double rp = r_jph[Nr-1]/rescale; //double rm =-r_jph[Nr-1]/rescale; double rm = r_jph[-1]/rescale; double zp = z_kph[Nz-1]/rescale; double zm = z_kph[ -1]/rescale; glVertex3f( rp-xoff , -yoff+zoff , zp ); glVertex3f( rm-xoff , -yoff+zoff , zp ); glVertex3f( rm-xoff , -yoff+zoff , zm ); glVertex3f( rp-xoff , -yoff+zoff , zm ); glEnd(); } } } } if( draw_bar ){ double xb = 0.6; double hb = 1.0; double wb = 0.02; int Nb = 1000; double dy = hb/(double)Nb; int k; for( k=0 ; k<Nb ; ++k ){ double y = (double)k*dy - .5*hb; double val = (double)k/(double)Nb; float rrr,ggg,bbb; get_rgb( val , &rrr , &ggg , &bbb , cmap ); glLineWidth(0.0f); glColor3f( rrr , ggg , bbb ); glBegin(GL_POLYGON); glVertex3f( xb , y , camdist + .001 ); glVertex3f( xb+wb , y , camdist + .001 ); glVertex3f( xb+wb , y+dy , camdist + .001 ); glVertex3f( xb , y+dy , camdist + .001 ); glEnd(); } int Nv = 8; for( k=0 ; k<Nv ; ++k ){ double y = (double)k*hb/(double)(Nv-1) - .5*hb; double val = (double)k/(double)(Nv-1)*(maxval-minval) + minval; char valname[256]; sprintf(valname,"%+.2e",val); glLineWidth(1.0f); glColor3f(0.0,0.0,0.0); glBegin(GL_LINE_LOOP); glVertex3f( xb , y , camdist + .0011 ); glVertex3f( xb+wb , y , camdist + .0011 ); glEnd(); glutPrint( xb+1.5*wb , y-.007 , camdist + .001 ,glutFonts[6] , valname , 0.0f, 0.0f , 0.0f , 0.5f ); } } if( draw_planet ){ double eps = 0.01; int p; for( p=0 ; p<Npl ; ++p ){ double r = thePlanets[p][0]/rescale; double phi = thePlanets[p][1]; if( t_off && !p_off ) phi -= t; if( p_off ) phi -= thePlanets[1][1]; glColor3f(0.0,0.0,0.0); glLineWidth(2.0); glBegin(GL_LINE_LOOP); glVertex3f( r*cos(phi)-xoff+eps , r*sin(phi)-yoff+eps , camdist+.001 ); glVertex3f( r*cos(phi)-xoff-eps , r*sin(phi)-yoff+eps , camdist+.001 ); glVertex3f( r*cos(phi)-xoff-eps , r*sin(phi)-yoff-eps , camdist+.001 ); glVertex3f( r*cos(phi)-xoff+eps , r*sin(phi)-yoff-eps , camdist+.001 ); glEnd(); } } if( draw_spiral ){ double rp = 5.0;//thePlanets[1][0]; double Mach = 3.65; double p0 = 1.2; double dr = .07; int Nr = 200; double Rmin = 0.5; double Rmax = 1.1; int k; glLineWidth(3.0f); glColor3f(0.0,0.0,0.0); //glColor3f(1.0,1.0,1.0); glBegin(GL_LINE_LOOP); for( k=0 ; k<Nr ; ++k ){ //double phi0 = ((double)k+.5)/(double)Nr*2.*M_PI;//(3.-2.*sqrt(1./r)-r)*20.; double x = ((double)k+.5)/(double)Nr; //double r = .001*pow(.5/.001,x); double r = .5*pow(1.5/.5,x); //double phi0 = p0-log(r/0.001)*Mach;//(3.-2.*sqrt(1./r)-r)*5.; double phi0 = (3.-2.*sqrt(1./r)-r)*20.; if( r<1. ) phi0 = -phi0; // double x0 = rp + dr*cos(phi0); // double y0 = dr*sin(phi0); double phi = phi0; // double r = rp; // double phi = atan2(y0,x0); // double phi = ((double)k+.5)/(double)Nr*2.*M_PI*9.32 + 4.*M_PI; // double r = sqrt(x0*x0+y0*y0); // double r = pow(phi/10.,-2.); // double r = 2./(1.+sin(phi));//1.0;//((double)k+0.5)/(double)Nr*(Rmax-Rmin) + Rmin; // if( r<1. ) phi = -phi; r /= rescale; glVertex3f( r*cos(phi)-xoff , r*sin(phi)-yoff , camdist + .0011 ); if( k%2==1 ){ glEnd(); glBegin(GL_LINE_LOOP); } } glEnd(); /* e += 0.01; glBegin(GL_LINE_LOOP); for( k=0 ; k<Nr ; ++k ){ double phi0 = ((double)k-.5)/(double)Nr*2.*M_PI;//(3.-2.*sqrt(1./r)-r)*20.; double x0 = 1.+e*cos(phi0); double y0 = e*sin(phi0); double phi = atan2(y0,x0); double r = sqrt(x0*x0+y0*y0); // double phi = (double)k/(double)Nr*2.*M_PI;//(3.-2.*sqrt(1./r)-r)*20.; // double r = 2./(1.+sin(phi));//1.0;//((double)k+0.5)/(double)Nr*(Rmax-Rmin) + Rmin; // if( r<1. ) phi = -phi; r /= rescale; glVertex3f( r*cos(phi)-xoff , r*sin(phi)-yoff , camdist + .0011 ); if( k%2==1 ){ glEnd(); glBegin(GL_LINE_LOOP); } } glEnd(); */ } } if( draw_t ){ char tprint[256]; sprintf(tprint,"t = %.2e",t/2./M_PI); glutPrint( -.6 , .5 , camdist + .001 , glutFonts[6] , tprint , 0.0f, 0.0f , 0.0f , 0.5f ); // sprintf(tprint,"uMax = %.1f",uMax); // glutPrint( -.8 , .4 , camdist + .001 , glutFonts[6] , tprint , 0.0f, 0.0f , 0.0f , 0.5f ); } if( help_screen ){ int NLines = 9; double dy = -.04; char help[NLines][256]; sprintf(help[0],"Help Display:"); sprintf(help[1],"b - Toggle Colorbar"); sprintf(help[2],"c - Change Colormap"); sprintf(help[3],"f - Toggle Max/Min Floors"); sprintf(help[4],"p - Toggle Planet Data"); sprintf(help[5],"1-9 - Choose Primitive Variable to Display"); sprintf(help[6],"wasd - Move Camera"); sprintf(help[7],"z/x - Zoom in/out"); sprintf(help[8],"h - Toggle Help Screen"); int i; for( i=0 ; i<NLines ; ++i ){ glutPrint( -.8 , i*dy , camdist + .001 , glutFonts[6] , help[i] , 0.0f, 0.0f , 0.0f , 0.5f ); } } if( CommandMode ){ TakeScreenshot("out.ppm"); exit(1); } glutSwapBuffers(); }
void bt459_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect, u8 *pixel_data) { // initialise the blink timer if (m_blink_start > screen.frame_number()) m_blink_start = screen.frame_number(); // compute the blink state according to the programmed duty cycle const bool blink_state = ((screen.frame_number() - m_blink_start) & ( (m_command_0 & CR0302) == CR0302_1616 ? 0x10 : (m_command_0 & CR0302) == CR0302_3232 ? 0x20 : (m_command_0 & CR0302) == CR0302_6464 ? 0x40 : 0x30)) == 0; // compute the pixel mask from the pixel read mask and blink mask/state const u8 pixel_mask = m_pixel_read_mask & (blink_state ? 0xffU : ~m_pixel_blink_mask); // draw visible pixel data switch (m_command_0 & CR0100) { case CR0100_1BPP: for (int y = screen.visible_area().min_y; y <= screen.visible_area().max_y; y++) for (int x = screen.visible_area().min_x; x <= screen.visible_area().max_x; x += 8) { u8 data = *pixel_data++; bitmap.pix(y, x + 7) = get_rgb(data & 0x1, pixel_mask); data >>= 1; bitmap.pix(y, x + 6) = get_rgb(data & 0x1, pixel_mask); data >>= 1; bitmap.pix(y, x + 5) = get_rgb(data & 0x1, pixel_mask); data >>= 1; bitmap.pix(y, x + 4) = get_rgb(data & 0x1, pixel_mask); data >>= 1; bitmap.pix(y, x + 3) = get_rgb(data & 0x1, pixel_mask); data >>= 1; bitmap.pix(y, x + 2) = get_rgb(data & 0x1, pixel_mask); data >>= 1; bitmap.pix(y, x + 1) = get_rgb(data & 0x1, pixel_mask); data >>= 1; bitmap.pix(y, x + 0) = get_rgb(data & 0x1, pixel_mask); } break; case CR0100_2BPP: for (int y = screen.visible_area().min_y; y <= screen.visible_area().max_y; y++) for (int x = screen.visible_area().min_x; x <= screen.visible_area().max_x; x += 4) { u8 data = *pixel_data++; bitmap.pix(y, x + 3) = get_rgb(data & 0x3, pixel_mask); data >>= 2; bitmap.pix(y, x + 2) = get_rgb(data & 0x3, pixel_mask); data >>= 2; bitmap.pix(y, x + 1) = get_rgb(data & 0x3, pixel_mask); data >>= 2; bitmap.pix(y, x + 0) = get_rgb(data & 0x3, pixel_mask); } break; case CR0100_4BPP: for (int y = screen.visible_area().min_y; y <= screen.visible_area().max_y; y++) for (int x = screen.visible_area().min_x; x <= screen.visible_area().max_x; x += 2) { u8 data = *pixel_data++; bitmap.pix(y, x + 1) = get_rgb(data & 0x7, pixel_mask); data >>= 4; bitmap.pix(y, x + 0) = get_rgb(data & 0x7, pixel_mask); } break; case CR0100_8BPP: for (int y = screen.visible_area().min_y; y <= screen.visible_area().max_y; y++) for (int x = screen.visible_area().min_x; x <= screen.visible_area().max_x; x++) bitmap.pix(y, x) = get_rgb(*pixel_data++, pixel_mask); break; } // draw cursors when visible and not blinked off if ((m_cursor_command & (CR47 | CR46 | CR45 | CR44)) && ((m_cursor_command & CR40) == 0 || blink_state)) { // get 64x64 bitmap and cross hair cursor plane enable const u8 bm_cursor_enable = (m_cursor_command & (CR47 | CR46)) >> 6; const u8 ch_cursor_enable = (m_cursor_command & (CR45 | CR44)) >> 4; // get cross hair cursor half thickness const int ch_thickness = (m_cursor_command & CR4241) >> 1; /* * The cursor (x) value to be written is calculated as follows: * * Cx = desired display screen (x) position + H - P * * where * * P = 37 if 1:1 input multiplexing, 52 if 4:1 input multiplexing, * 57 if 5:1 input multiplexing * H = number of pixels between the first rising edge of LD* * following the falling edge of HSYNC* to active video * * The cursor (y) value to be written is calculated as follows: * * Cy = desired display screen (y) position + V - 32 * * where * * V = number of scan lines from the second sync pulse during * vertical blanking to active video * * Values from $0FC0 (-64) to $0FBF (+4031) may be loaded into the * cursor (y) register. The negative values ($0FC0 to $0FFF) are used * in situations where V < 32, and the cursor must be moved off the * top of the screen. */ const int cursor_x = m_cursor_x + ( (m_command_0 & CR0706) == CR0706_11MPX ? 37 : (m_command_0 & CR0706) == CR0706_41MPX ? 52 : (m_command_0 & CR0706) == CR0706_51MPX ? 57 : 0); const int cursor_y = (m_cursor_y < 0xfc0 ? m_cursor_y : m_cursor_y - 0x1000) + 32; // 64x64 bitmap cursor if (bm_cursor_enable) { // compute target 64x64 rectangle rectangle cursor(cursor_x - 31, cursor_x + 32, cursor_y - 31, cursor_y + 32); // intersect with screen bitmap cursor &= bitmap.cliprect(); // draw if any portion is visible if (!cursor.empty()) { for (int y = 0; y < 64; y++) { // get screen y pixel coordinate const int ypos = cursor_y - 31 + y; for (int x = 0; x < 64; x++) { // get screen x pixel coordinate const int xpos = cursor_x - 31 + x; // check if pixel is visible if (cursor.contains(xpos, ypos)) { // retrieve 2 bits of 64x64 bitmap cursor data u8 data = (m_cursor_ram[y * 16 + (x >> 2)] >> ((3 - (x & 3)) << 1)) & bm_cursor_enable; // check for dual-cursor mode and combine with cross-hair data if (ch_cursor_enable) if (((x >= 31 - ch_thickness) && (x <= 31 + ch_thickness)) || ((y >= 31 - ch_thickness) && (y <= 31 + ch_thickness))) data = (m_cursor_command & CR43) ? data | ch_cursor_enable : data ^ ch_cursor_enable; // write cursor data to screen (normal or X Window mode) if (data && !((m_command_2 & CR21) && data == 1)) bitmap.pix(ypos, xpos) = m_cursor_color[data - 1]; } } } } } // cross hair cursor if (ch_cursor_enable) { // get the cross hair cursor color const rgb_t ch_color = m_cursor_color[ch_cursor_enable - 1]; /* * The window (x) value to be written is calculated as follows: * * Wx = desired display screen (x) position + H - P * * where * * P = 5 if 1:1 input multiplexing, 20 if 4:1 input multiplexing, * 25 if 5:1 input multiplexing * H = number of pixels between the first rising edge of LD* * following the falling edge of HSYNC* to active video * * The window (y) value to be written is calculated as follows: * * Wy = desired display screen (y) position + V * * where * * V = number of scan lines from the second sync pulse during * vertical blanking to active video * * Values from $0000 to $0FFF may be written to the window (x) and * (y) registers. A full-screen cross hair is implemented by * loading the window (x,y) registers with $0000, and the window * width and height registers with $0FFF. */ const bool full_screen = (m_window_x == 0 && m_window_y == 0 && m_window_w == 0x0fff && m_window_h == 0x0fff); const int window_x = full_screen ? screen.visible_area().min_x : m_window_x + ( (m_command_0 & CR0706) == CR0706_11MPX ? 5 : (m_command_0 & CR0706) == CR0706_41MPX ? 20 : (m_command_0 & CR0706) == CR0706_51MPX ? 25 : 0); const int window_y = full_screen ? screen.visible_area().min_y : m_window_y; /* * The actual window width is 2, 8 or 10 pixels more than the * value specified by the window width register, depending on * whether 1:1, 4:1 or 5:1 input multiplexing is specified. The * actual window height is 2 pixels more than the value specified * by the window height register. Therefore, the minimum window * width is 2, 8 or 10 pixels for 1:1, 4:1 and 5:1 multiplexing, * respectively. The minimum window height is 2 pixels. * * Values from $0000 to $0FFF may be written to the window width * and height registers. * * Note: testing indicates the cross-hair cursor should be drawn * strictly inside the window, although this is not 100% clear from * the documentation. */ const int window_w = full_screen ? screen.visible_area().width() : m_window_w + ( (m_command_0 & CR0706) == CR0706_11MPX ? 2 : (m_command_0 & CR0706) == CR0706_41MPX ? 8 : (m_command_0 & CR0706) == CR0706_51MPX ? 10 : 0); const int window_h = full_screen ? screen.visible_area().height() : m_window_h + 2; // check for dual-cursor mode if (bm_cursor_enable) { // draw the cross hair cursor as vertical and horizontal filled rectangles broken by the 64x64 cursor area rectangle v1(cursor_x - ch_thickness, cursor_x + ch_thickness, window_y + 1, cursor_y - 32); rectangle v2(cursor_x - ch_thickness, cursor_x + ch_thickness, cursor_y + 33, window_y + window_h); rectangle h1(window_x + 1, cursor_x - 32, cursor_y - ch_thickness, cursor_y + ch_thickness); rectangle h2(cursor_x + 33, window_x + window_w, cursor_y - ch_thickness, cursor_y + ch_thickness); v1 &= bitmap.cliprect(); v2 &= bitmap.cliprect(); h1 &= bitmap.cliprect(); h2 &= bitmap.cliprect(); if (!v1.empty()) bitmap.fill(ch_color, v1); if (!v2.empty()) bitmap.fill(ch_color, v2); if (!h1.empty()) bitmap.fill(ch_color, h1); if (!h2.empty()) bitmap.fill(ch_color, h2); } else { // draw the cross hair cursor as unbroken vertical and horizontal filled rectangles rectangle v(cursor_x - ch_thickness, cursor_x + ch_thickness, window_y + 1, window_y + window_h); rectangle h(window_x + 1, window_x + window_w, cursor_y - ch_thickness, cursor_y + ch_thickness); v &= bitmap.cliprect(); h &= bitmap.cliprect(); if (!v.empty()) bitmap.fill(ch_color, v); if (!h.empty()) bitmap.fill(ch_color, h); } } }
void ccv(const cv::Mat &src, feature_ccv &ret) { boost::shared_array<uint32_t> labeled; boost::unordered_map<uint32_t, label_info> labels; cv::Mat resized; int i; if (src.channels() != 3) return; cv::resize(src, resized, cv::Size(ccv_width, ccv_height)); cv::GaussianBlur(resized, resized, cv::Size(3, 3), 0); ret.m_alpha = feature_ccv::float_arr(new float[NUM_CCV_COLOR]); ret.m_beta = feature_ccv::float_arr(new float[NUM_CCV_COLOR]); for (i = 0; i < NUM_CCV_COLOR; i++) { ret.m_alpha[i] = 0.0f; ret.m_beta[i] = 0.0f; } label_info info; rgb color; uint32_t label; int size; size = ccv_width * ccv_height; labeled = boost::shared_array<uint32_t>(new uint32_t[size]); get_rgb(color, resized, 0, 0); label = 0; labeled[0] = label; info.m_color = color; info.m_alias = label; info.m_count = 1; labels[label] = info; int x, y; for (x = 1; x < ccv_width; x++) { rgb color_here, color_left; get_rgb(color_here, resized, x, 0); get_rgb(color_left, resized, x - 1, 0); if (color_here == color_left) { labels[label].m_count++; labeled[x] = label; } else { label++; labeled[x] = label; info.m_color = color_here; info.m_alias = label; info.m_count = 1; labels[label] = info; } } for (y = 1; y < ccv_height; y++) { rgb c_here, c_left, c_above, c_above_l, c_above_r; for (x = 0; x < ccv_width; x++) { get_rgb(c_here, resized, x, y); if (x == 0) { c_left.m_color32 = 0xffffffff; c_above_l.m_color32 = 0xffffffff; } if (x + 1 < ccv_width) get_rgb(c_above_r, resized, x + 1, y - 1); else c_above_r.m_color32 = 0xffffffff; get_rgb(c_above, resized, x, y - 1); uint32_t same[4]; uint32_t l; int num_same = 0; if (c_here == c_left) { l = labeled[x - 1 + y * ccv_width]; same[num_same] = find_label(l, labels); num_same++; } if (c_here == c_above) { l = labeled[x + (y - 1) * ccv_width]; same[num_same] = find_label(l, labels); num_same++; } if (c_here == c_above_l) { l = labeled[x - 1 + (y - 1) * ccv_width]; same[num_same] = find_label(l, labels); num_same++; } if (c_here == c_above_r) { l = labeled[x + 1 + (y - 1) * ccv_width]; same[num_same] = find_label(l, labels); num_same++; } if (num_same > 0) { boost::unordered_map<uint32_t, label_info>::iterator it1, it2; uint32_t label_min = same[0]; for (i = 1; i < num_same; i++) { if (same[i] < label_min) { label_min = same[i]; } } it1 = labels.find(label_min); it1->second.m_count++; for (i = 0; i < num_same; i++) { if (label_min < same[i]) { it2 = labels.find(same[i]); int count = it2->second.m_count; it2->second.m_alias = label_min; it2->second.m_count = 0; it1->second.m_count += count; } } labeled[x + y * ccv_width] = label_min; } else { label++; labeled[x + y * ccv_width] = label; info.m_color = c_here; info.m_alias = label; info.m_count = 1; labels[label] = info; } } c_left = c_here; c_above = c_above_r; c_above_l = c_above; } boost::unordered_map<uint32_t, label_info>::iterator it; for (it = labels.begin(); it != labels.end(); ++it) { int idx; idx = rgb2idx(it->second.m_color); if (it->second.m_count > t_ccv) { ret.m_alpha[idx] += it->second.m_count; } else { ret.m_beta[idx] += it->second.m_count; } } float num_pix = ccv_width * ccv_height; for (i = 0; i < NUM_CCV_COLOR; i++) { ret.m_alpha[i] /= num_pix; ret.m_beta[i] /= num_pix; } }