/** * Initialize the opticflow calculator * @param[out] *opticflow The new optical flow calculator * @param[in] *w The image width * @param[in] *h The image height */ void opticflow_calc_init(struct opticflow_t *opticflow, uint16_t w, uint16_t h) { /* Create the image buffers */ image_create(&opticflow->img_gray, w, h, IMAGE_GRAYSCALE); image_create(&opticflow->prev_img_gray, w, h, IMAGE_GRAYSCALE); /* Set the previous values */ opticflow->got_first_img = FALSE; opticflow->prev_phi = 0.0; opticflow->prev_theta = 0.0; /* Set the default values */ opticflow->max_track_corners = OPTICFLOW_MAX_TRACK_CORNERS; opticflow->window_size = OPTICFLOW_WINDOW_SIZE; opticflow->subpixel_factor = OPTICFLOW_SUBPIXEL_FACTOR; opticflow->max_iterations = OPTICFLOW_MAX_ITERATIONS; opticflow->threshold_vec = OPTICFLOW_THRESHOLD_VEC; opticflow->fast9_adaptive = OPTICFLOW_FAST9_ADAPTIVE; opticflow->fast9_threshold = OPTICFLOW_FAST9_THRESHOLD; opticflow->fast9_min_distance = OPTICFLOW_FAST9_MIN_DISTANCE; }
// the *other* style menu background void menu_background2_create(texture *tex, int w, int h) { image img; image_create(&img, w, h); image_clear(&img, COLOR_MENU_BG); for(int x = 5; x < w; x += 5) { image_line(&img, x, 0, x, h-1, COLOR_MENU_LINE2); } for(int y = 4; y < h; y += 5) { image_line(&img, 0, y, w-1, y, COLOR_MENU_LINE2); } image_rect(&img, 1, 1, w-2, h-2, COLOR_MENU_BORDER2); image_rect(&img, 0, 0, w-2, h-2, COLOR_MENU_BORDER1); texture_create_from_img(tex, &img); image_free(&img); }
/* creates the background */ image_t* create_background() { image_t* img = image_create(VIDEO_SCREEN_W, VIDEO_SCREEN_H); font_t *fnt = font_create("disclaimer"); v2d_t camera = v2d_new(VIDEO_SCREEN_W/2, VIDEO_SCREEN_H/2); image_clear(video_get_backbuffer(), image_rgb(0,0,0)); font_set_width(fnt, VIDEO_SCREEN_W - 6); font_set_text(fnt, "%s", text); font_set_position(fnt, v2d_new(3,3)); font_render(fnt, camera); image_blit(video_get_backbuffer(), img, 0, 0, 0, 0, image_width(img), image_height(img)); font_destroy(fnt); return img; }
int main(int argc, char *argv[]) { Image *src; src = image_create(750, 1000); //src = image_read("1view.ppm"); mandelbrot( src, 1.755, -0.02, 0.02); //mandelbrot( src, -1.0, -1.0, 3.0); //julia( src, -2.0, -2.0, 4.0); //image_noise( src, 50); image_write( src, "fractal.ppm"); image_free( src ); return(0); }
struct image_t* video_crop_func(struct image_t* img) { uint8_t *imgbuf = img->buf; if (imgCrop == NULL) { imgCrop = malloc(sizeof(struct image_t)); image_create(imgCrop,Wcrop,Hcrop,IMAGE_YUV422); } uint8_t *imgCropbuf = imgCrop->buf; for (uint16_t y = 0; y < Hcrop; y++) { for (uint16_t x = 0; x < Wcrop; x += 2) { // //CROPS A CENTERED Hcrop BY Wcrop IMAGE // //CROP INTO THE CORNER OF THE ORIGINAL IMAGE // imgbuf[y*img->w*2+x*2] = imgbuf[img->w*2*((img->h-Hcrop)/2+y)+(img->w-Wcrop)+x*2]; // imgbuf[y*img->w*2+x*2+1] = imgbuf[img->w*2*((img->h-Hcrop)/2+y)+(img->w-Wcrop)+x*2+1]; // imgbuf[y*img->w*2+x*2+2] = imgbuf[img->w*2*((img->h-Hcrop)/2+y)+(img->w-Wcrop)+x*2+2]; // imgbuf[y*img->w*2+x*2+3] = imgbuf[img->w*2*((img->h-Hcrop)/2+y)+(img->w-Wcrop)+x*2+3]; // //CROP INTO NEW IMAGE // imgCropbuf[y*Wcrop*2+x*2] = imgbuf[img->w*2*((img->h-Hcrop)/2+y)+(img->w-Wcrop)+x*2]; // imgCropbuf[y*Wcrop*2+x*2+1] = imgbuf[img->w*2*((img->h-Hcrop)/2+y)+(img->w-Wcrop)+x*2+1]; // imgCropbuf[y*Wcrop*2+x*2+2] = imgbuf[img->w*2*((img->h-Hcrop)/2+y)+(img->w-Wcrop)+x*2+2]; // imgCropbuf[y*Wcrop*2+x*2+3] = imgbuf[img->w*2*((img->h-Hcrop)/2+y)+(img->w-Wcrop)+x*2+3]; // //CROPS A UNCENTERED Hcrop BY Wcrop IMAGE //CROP INTO THE CORNER OF THE ORIGINAL IMAGE imgbuf[y*img->w*2+x*2] = imgbuf[img->w*2*((img->h-Hcrop)/2-displacement+y)+(img->w-Wcrop)+x*2]; imgbuf[y*img->w*2+x*2+1] = imgbuf[img->w*2*((img->h-Hcrop)/2-displacement+y)+(img->w-Wcrop)+x*2+1]; imgbuf[y*img->w*2+x*2+2] = imgbuf[img->w*2*((img->h-Hcrop)/2-displacement+y)+(img->w-Wcrop)+x*2+2]; imgbuf[y*img->w*2+x*2+3] = imgbuf[img->w*2*((img->h-Hcrop)/2-displacement+y)+(img->w-Wcrop)+x*2+3]; //CROP INTO NEW IMAGE imgCropbuf[y*Wcrop*2+x*2] = imgbuf[img->w*2*((img->h-Hcrop)/2-displacement+y)+(img->w-Wcrop)+x*2]; imgCropbuf[y*Wcrop*2+x*2+1] = imgbuf[img->w*2*((img->h-Hcrop)/2-displacement+y)+(img->w-Wcrop)+x*2+1]; imgCropbuf[y*Wcrop*2+x*2+2] = imgbuf[img->w*2*((img->h-Hcrop)/2-displacement+y)+(img->w-Wcrop)+x*2+2]; imgCropbuf[y*Wcrop*2+x*2+3] = imgbuf[img->w*2*((img->h-Hcrop)/2-displacement+y)+(img->w-Wcrop)+x*2+3]; } } // DOESNT WORK REUSING THE SAME IMAGE BECAUSE RESIZING CAUSES PROBLEMS WITH THE NEXT FRAME // img->w = Wcrop; // img->h = Hcrop; // img->buf_size = Wcrop*Hcrop*2; // img->buf = realloc(img->buf, img->buf_size); return imgCrop; // return img; }
image_t render(sphere_t *spheres, int nspheres, unsigned width, unsigned height, int depth) { struct vector raydir; /* Ray direction. */ unsigned x, y; float xx, yy; image_t img; float invwidth; /* width^-1 */ float invheight; /* height^-1 */ float angle; float fov; struct vector pixel; float aspectratio; /* Image's aspect ratio. */ max_depth = depth; img = image_create(width, height); invwidth = 1.0 / width; invheight = 1.0 /height; fov = 30; aspectratio = width / ((float)height); angle = tan(PI*0.5*fov/180.0); for (y = 0; y < height; ++y) { #pragma omp parallel for \ default(shared) private(x,xx,yy,raydir,pixel) schedule(dynamic) for (x = 0; x < width; x++) { xx = (2 * ((x + 0.5) * invwidth) - 1) * angle * aspectratio; yy = (1 - 2 * ((y + 0.5) * invheight)) * angle; raydir = vector_normalize(VECTOR(xx, yy, -1)); pixel = raytrace(VECTOR(0, 0, 0), raydir, spheres, nspheres, 0); IMAGE(img, x, y).r = (unsigned char) (min(1.0, pixel.x)*255); IMAGE(img, x, y).g = (unsigned char) (min(1.0, pixel.y)*255); IMAGE(img, x, y).b = (unsigned char) (min(1.0, pixel.z)*255); } } return (img); }
void progressbar_create_block(progress_bar *bar) { float prog = bar->percentage / 100.0f; int w = bar->w * prog; if(w > 0) { image tmp; image_create(&tmp, w, bar->h); image_clear(&tmp, bar->int_bg_color); image_rect_bevel(&tmp, 0, 0, w - 1, bar->h-1, bar->int_topleft_color, bar->int_bottomright_color, bar->int_bottomright_color, bar->int_topleft_color); texture_create(&bar->block); texture_init_from_img(&bar->block, &tmp); image_free(&tmp); } }
void motion_sensor_transform(MotionSensor *sensor, Image **frame) { int height = (*frame)->height; int width = (*frame)->width; int n_channels = (*frame)->n_channels; int n_elements = height * width * n_channels; Image *result = image_create(height, width, n_channels); if (sensor->last_frame) for (int i = 0; i < n_elements; ++i) result->data[i] = fabsf((*frame)->data[i] - sensor->last_frame->data[i]); else for (int i = 0; i < n_elements; ++i) result->data[i] = 0.0f; image_release(sensor->last_frame); sensor->last_frame = *frame; *frame = result; }
/** * 建立 src 图像的灰度版本 * * @param src 源图像 * @param gray 灰度 0 到 100, 0 为源图像, 100 为纯灰色图像 */ image_p create_gray_image(image_p src, int gray) { uint32_t y,x; image_p pimg; uint16_t *p16 = NULL,*psrc16 = NULL; uint32_t *p32 = NULL,*psrc32 = NULL; if(gray<0 || gray>100) { nge_print("create_gray_image arg 'gray' must between 0 to 100!"); return NULL; } CHECK_AND_UNSWIZZLE(src); pimg = image_create(src->w, src->h, src->dtype); for(y=0;y<src->h;y++) { if(src->dtype == DISPLAY_PIXEL_FORMAT_8888) { p32 = (uint32_t *)pimg->data + y*src->texw; psrc32 = (uint32_t *)src->data + y*src->texw; } else { p16 = (uint16_t *)pimg->data + y*src->texw; psrc16 = (uint16_t *)src->data + y*src->texw; } for(x=0;x<src->w;x++) { if(src->dtype == DISPLAY_PIXEL_FORMAT_8888) { *(p32 + x) = (uint32_t)get_gray_color(pimg->dtype, *(psrc32 + x), gray); } else { *(p16 + x) = (uint16_t)get_gray_color(pimg->dtype, *(psrc16 + x), gray); } } } CHECK_AND_SWIZZLE(src); return pimg; }
struct image_t* detect_window(struct image_t *img) { uint16_t coordinate[2]; coordinate[0] = 0; coordinate[1] = 0; uint16_t response = 0; uint32_t integral_image[img->w * img->h]; struct image_t gray; image_create(&gray, img->w, img->h, IMAGE_GRAYSCALE); image_to_grayscale(img, &gray); response = detect_window_sizes((uint8_t *)gray.buf, (uint32_t)img->w, (uint32_t)img->h, coordinate, integral_image, MODE_BRIGHT); printf("Coordinate: %d, %d\n", coordinate[0], coordinate[1]); printf("Response = %d\n", response); image_free(&gray); return NULL; // No new image was created }
bool_t cv_window_func(struct image_t *img) { if (!window_enabled) return FALSE; uint16_t coordinate[2] = {0,0}; uint16_t response = 0; uint32_t integral_image[img->w * img->h]; struct image_t gray; image_create(&gray, img->w, img->h, IMAGE_GRAYSCALE); image_to_grayscale(img, &gray); response = detect_window_sizes( (uint8_t*)gray.buf, (uint32_t)img->w, (uint32_t)img->h, coordinate, integral_image, MODE_BRIGHT); image_free(&gray); // Display the marker location and center-lines. int px = coordinate[0] & 0xFFFe; int py = coordinate[1] & 0xFFFe; if (response < 92) { for (int y = 0; y < img->h-1; y++) { Img(px, y) = 65; Img(px+1, y) = 255; } for (int x = 0; x < img->w-1; x+=2) { Img(x, py) = 65; Img(x+1, py) = 255; } uint32_t temp = coordinate[0]; temp = temp << 16; temp += coordinate[1]; blob_locator = temp; } return FALSE; }
int main(int argc, char *argv[]) { struct display *d; int i; int image_counter = 0; d = display_create(&argc, argv); if (d == NULL) { fprintf(stderr, "failed to create display: %m\n"); return -1; } for (i = 1; i < argc; i++) image_create(d, argv[i], &image_counter); if (image_counter > 0) display_run(d); return 0; }
void vgWritePixels(const void * data, VGint dataStride, VGImageFormat dataFormat, VGint dx, VGint dy, VGint width, VGint height) { struct vg_context *ctx = vg_current_context(); struct pipe_context *pipe = ctx->pipe; if (!supported_image_format(dataFormat)) { vg_set_error(ctx, VG_UNSUPPORTED_IMAGE_FORMAT_ERROR); return; } if (!data || !is_aligned(data)) { vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR); return; } if (width <= 0 || height <= 0) { vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR); return; } vg_validate_state(ctx); { struct vg_image *img = image_create(dataFormat, width, height); image_sub_data(img, data, dataStride, dataFormat, 0, 0, width, height); #if 0 struct matrix *matrix = &ctx->state.vg.image_user_to_surface_matrix; matrix_translate(matrix, dx, dy); image_draw(img); matrix_translate(matrix, -dx, -dy); #else /* this looks like a better approach */ image_set_pixels(dx, dy, img, 0, 0, width, height); #endif image_destroy(img); } /* make sure rendering has completed */ pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE, NULL); }
void video_capture_save(struct image_t *img) { // Declare storage for image location char save_name[128]; // Simple shot counter to find first available image location for (/* no init */; video_capture_index < 9999; ++video_capture_index) { // Generate image location sprintf(save_name, "%s/img_%05d.jpg", STRINGIFY(VIDEO_CAPTURE_PATH), video_capture_index); // Continue with next number if file exists already if (access(save_name, F_OK) != -1) { continue; } printf("[video_capture] Saving image to %s.\n", save_name); // Open file FILE *fp = fopen(save_name, "w"); if (fp == NULL) { printf("[video_capture] Could not write shot %s.\n", save_name); break; } // Create jpg image from raw frame struct image_t img_jpeg; image_create(&img_jpeg, img->w, img->h, IMAGE_JPEG); jpeg_encode_image(img, &img_jpeg, VIDEO_CAPTURE_JPEG_QUALITY, true); // Save it to the file and close it fwrite(img_jpeg.buf, sizeof(uint8_t), img_jpeg.buf_size, fp); fclose(fp); // Free image image_free(&img_jpeg); // End loop here break; } }
int main(int argc, char *argv[]) { struct display *d; int i; d = display_create(&argc, &argv, option_entries); if (d == NULL) { fprintf(stderr, "failed to create display: %m\n"); return -1; } for (i = 1; i < argc; i++) { struct image *image; image = image_create (d, i, argv[i]); } display_run(d); return 0; }
void progressbar_create(progress_bar *bar, unsigned int x, unsigned int y, unsigned int w, unsigned int h, color border_topleft_color, color border_bottomright_color, color bg_color, color int_topleft_color, color int_bottomright_color, color int_bg_color, int orientation) { bar->x = x; bar->y = y; bar->w = w; bar->h = h; bar->orientation = orientation; bar->percentage = 100; bar->int_topleft_color = int_topleft_color; bar->int_bottomright_color = int_bottomright_color; bar->int_bg_color = int_bg_color; texture_create(&bar->block); texture_create(&bar->background); // Background, image tmp; image_create(&tmp, w, h); image_clear(&tmp, bg_color); image_rect_bevel(&tmp, 0, 0, w-1, h-1, border_topleft_color, border_bottomright_color, border_bottomright_color, border_topleft_color); texture_init_from_img(&bar->background, &tmp); image_free(&tmp); // Bar progressbar_create_block(bar); }
/** * Function adds image into image pile and stores some basic information * about it. * * \param filename path to the file * \param size size of the file in bytes * \param time time of the last modification in epoch * \return OK */ RCode pile_load_file(const gchar* filename, guint size, time_t time) { Image* tmp_image = NULL; ASSERT(NULL != filename); if ( 0 != g_access(filename, R_OK) ) { TRACE_MESSAGE(PILE, TL_MAJOR, "File '%s' is not readable", filename); return FAIL; } if ( NULL == ( tmp_image = image_create(filename)) ) { /** \todo error logging */ return FAIL; } tmp_image->size = size; tmp_image->timestamp = time; pile_list_head = g_list_prepend(pile_list_head, (gpointer)tmp_image); return OK; }
void video_thread_periodic(void) { struct image_t img; image_create(&img, 320, 240, IMAGE_YUV422); int i, j; uint8_t u, v; #ifdef SMARTUAV_SIMULATOR SMARTUAV_IMPORT(&img); #else if (video_thread.is_running) { u = 0; v = 255; } else { u = 255; v = 0; } uint8_t *p = (uint8_t *) img.buf; for (j = 0; j < img.h; j++) { for (i = 0; i < img.w; i += 2) { *p++ = u; *p++ = j; *p++ = v; *p++ = j; } } video_thread.is_running = ! video_thread.is_running; #endif // Calling this function will not work because video_config_t is NULL (?) and img // has no timestamp // Commenting out for now // cv_run_device(NULL,&img); image_free(&img); }
/** * This function takes previous padded pyramid level and outputs next level of pyramid without padding. * For calculating new pixel value 5x5 filter matrix suggested by Bouguet is used: * [1/16 1/8 3/4 1/8 1/16]' x [1/16 1/8 3/4 1/8 1/16] * To avoid decimal numbers, all coefficients are multiplied by 10000. * * @param[in] *input - input image (grayscale only) * @param[out] *output - the output image * @param[in] border_size - amount of padding around image. Padding is made by reflecting image elements at the edge * Example: f e d c b a | a b c d e f | f e d c b a */ void pyramid_next_level(struct image_t *input, struct image_t *output, uint8_t border_size) { // Create output image, new image size is half the size of input image without padding (border) image_create(output, (input->w + 1 - 2 * border_size) / 2, (input->h + 1 - 2 * border_size) / 2, input->type); uint8_t *input_buf = (uint8_t *)input->buf; uint8_t *output_buf = (uint8_t *)output->buf; uint16_t row, col; // coordinates of the central pixel; pixel being calculated in input matrix; center of filer matrix uint16_t w = input->w; int32_t sum = 0; for (uint16_t i = 0; i != output->h; i++) { for (uint16_t j = 0; j != output->w; j++) { row = border_size + 2 * i; // First skip border, then every second pixel col = border_size + 2 * j; sum = 39 * (input_buf[(row - 2) * w + (col - 2)] + input_buf[(row - 2) * w + (col + 2)] + input_buf[(row + 2) * w + (col - 2)] + input_buf[(row + 2) * w + (col + 2)]); sum += 156 * (input_buf[(row - 2) * w + (col - 1)] + input_buf[(row - 2) * w + (col + 1)] + input_buf[(row - 1) * w + (col + 2)] + input_buf[(row + 1) * w + (col - 2)] + input_buf[(row + 1) * w + (col + 2)] + input_buf[(row + 2) * w + (col - 1)] + input_buf[(row + 2) * w + (col + 1)] + input_buf[(row - 1) * w + (col - 2)]); sum += 234 * (input_buf[(row - 2) * w + (col)] + input_buf[(row) * w + (col - 2)] + input_buf[(row) * w + (col + 2)] + input_buf[(row + 2) * w + (col)]); sum += 625 * (input_buf[(row - 1) * w + (col - 1)] + input_buf[(row - 1) * w + (col + 1)] + input_buf[(row + 1) * w + (col - 1)] + input_buf[(row + 1) * w + (col + 1)]); sum += 938 * (input_buf[(row - 1) * w + (col)] + input_buf[(row) * w + (col - 1)] + input_buf[(row) * w + (col + 1)] + input_buf[(row + 1) * w + (col)]); sum += 1406 * input_buf[(row) * w + (col)]; output_buf[i * output->w + j] = sum / 10000; } } }
/* reads a PPM image from the given filename. Initializes the alpha channel to 1.0 and the z channel to 1.0. Returns a NULL pointer if the operation fails. */ Image *image_read(char *filename) { int rows = 0; int cols = 0; int colors = 0; Pixel *image_array = readPPM(&rows, &cols, &colors, filename); // an array of pixels if (rows < 0 || cols < 0 ) { printf("rows: %d, cols: %d", rows, cols); return(NULL); } Image *image = image_create(rows, cols); for (int row=0;row<rows;row++) { for (int col=0;col<cols;col++) { image->data[row][col].rgb[0] = 256 - image_array[row*cols + col].r; image->data[row][col].rgb[1] = 256 - image_array[row*cols + col].g; image->data[row][col].rgb[2] = 256 - image_array[row*cols + col].b; image->data[row][col].a = 1.0; image->data[row][col].z = 1.0; } } return(image); }
int main(int argc, char *argv[]) { const int rows = 100; const int cols = 100; const int nFrames = 16; // View3D view3D; View2D view; //Matrix vtm; Matrix vtm, gtm, ltm; Polygon poly[16]; Point vp[4]; FILE *fp; fp = fopen("matrix_info.txt","w"); Image *src; int i, j, t; char filename[256]; Color color[6]; // set some colors color_set( &color[0], 0, 0, 1 ); // blue color_set( &color[1], 0, 1, 0 ); // green color_set( &color[2], 1, 0, 0 ); // red color_set( &color[3], 1, 0, 1 ); // magenta color_set( &color[4], 0, 1, 1 ); // cyan color_set( &color[5], 1, 1, 0 ); // yellow // optional theta value // if(argc > 1) { // theta = atoi(argv[1]); // } // initialize the three matrices matrix_identity(&vtm); matrix_identity(>m); matrix_identity(<m); // create image src = image_create( rows, cols ); srand ( time(NULL) ); for (i=0; i<16; i++){ for (j=0; j<4; j++){ point_set2D(&(vp[j]), rand()%cols, rand()%rows); } poly[i] = *(polygon_createp(4, vp)); } // grab command line argument to determine viewpoint // and set up the view structure if( argc > 1 ) { float alpha = atof( argv[1] ); if( alpha < 0.0 || alpha > 1.0 ){ alpha = 0.0; } point_set1( &(view.vrp), 3*alpha, 2*alpha, -2*alpha - (1.0-alpha)*3 ); } else { point_set1( &(view.vrp), 3, 2, -2 ); } vector_set( &(view.x), -view.vrp.val[0], -view.vrp.val[1], -view.vrp.val[2] ); view.dx = 1; // focal length view.screenx = cols; view.screeny = rows; matrix_setView2D( &vtm, &view ); matrix_print(&vtm, fp); // create image in arbitrary world coordinates for(t=0;t<nFrames;t++) { setWhite( src ); for (i=0; i<16; i++){ // need to add print statements to follow the ltm and polygons // Polygons not drawing matrix_identity(<m); matrix_translate2D(<m, -vp[0].val[0], -vp[0].val[1]); matrix_shear2D(<m, t, 0); matrix_translate2D(<m, vp[0].val[0], vp[0].val[1]); matrix_xformPolygon(<m, &poly[i]); matrix_xformPolygon(&vtm, &poly[i]); printf("begin scanline fill...\n"); polygon_drawFill(&poly[i], src, color[i%5]); printf("...end scanline fill\n"); } printf("hello: %d\n", t); sprintf(filename, "test5vt-%04d.ppm", t ); image_write( src, filename ); // translate the view across the scene point_set2D( &(view.vrp), 1.8 - 2.4*(t+1)/nFrames, 1.8 - 2.4*(t+1)/nFrames ); matrix_setView2D( &vtm, &view ); } fclose(fp); system("convert test5vt-*.ppm test5vt.gif"); //system("rm test5vt-*.ppm"); }
bool_t cv_blob_locator_func(struct image_t *img) { if (!blob_enabled) return 0; // Color Filter struct image_filter_t filter[2]; filter[0].y_min = color_lum_min; filter[0].y_max = color_lum_max; filter[0].u_min = color_cb_min; filter[0].u_max = color_cb_max; filter[0].v_min = color_cr_min; filter[0].v_max = color_cr_max; // Output image struct image_t dst; image_create(&dst, img->w, img->h, IMAGE_GRADIENT); // Labels uint16_t labels_count = 512; struct image_label_t labels[512]; // Blob finder image_labeling(img, &dst, filter, 1, labels, &labels_count); int largest_id = -1; int largest_size = 0; // Find largest for (int i=0; i<labels_count; i++) { // Only consider large blobs if (labels[i].pixel_cnt > 50) { if (labels[i].pixel_cnt > largest_size) { largest_size = labels[i].pixel_cnt; largest_id = i; } } } if (largest_id >= 0) { uint8_t *p = (uint8_t*) img->buf; uint16_t* l = (uint16_t*) dst.buf; for (int y=0;y<dst.h;y++) { for (int x=0;x<dst.w/2;x++) { if (l[y*dst.w+x] != 0xffff) { uint8_t c=0xff; if (l[y*dst.w+x] == largest_id) { c = 0; } p[y*dst.w*2+x*4]=c; p[y*dst.w*2+x*4+1]=0x80; p[y*dst.w*2+x*4+2]=c; p[y*dst.w*2+x*4+3]=0x80; } } } uint16_t cgx = labels[largest_id].x_sum / labels[largest_id].pixel_cnt * 2; uint16_t cgy = labels[largest_id].y_sum / labels[largest_id].pixel_cnt; if ((cgx > 1) && (cgx < (dst.w-2)) && (cgy > 1) && (cgy < (dst.h-2)) ) { p[cgy*dst.w*2+cgx*2-4] = 0xff; p[cgy*dst.w*2+cgx*2-2] = 0x00; p[cgy*dst.w*2+cgx*2] = 0xff; p[cgy*dst.w*2+cgx*2+2] = 0x00; p[cgy*dst.w*2+cgx*2+4] = 0xff; p[cgy*dst.w*2+cgx*2+6] = 0x00; p[(cgy-1)*dst.w*2+cgx*2] = 0xff; p[(cgy-1)*dst.w*2+cgx*2+2] = 0x00; p[(cgy+1)*dst.w*2+cgx*2] = 0xff; p[(cgy+1)*dst.w*2+cgx*2+2] = 0x00; } uint32_t temp = cgx; temp = temp << 16; temp += cgy; blob_locator = temp; } image_free(&dst); return 0; // No new image is available for follow up modules }
/** * @file lucas_kanade.c * * Compute the optical flow of several points using the pyramidal Lucas-Kanade algorithm by Yves Bouguet * The initial fixed-point implementation is done by G. de Croon and is adapted by * Freek van Tienen for the implementation in Paparazzi. * Pyramids implementation and related development done by Hrvoje Brezak. * @param[in] *new_img The newest grayscale image (TODO: fix YUV422 support) * @param[in] *old_img The old grayscale image (TODO: fix YUV422 support) * @param[in] *points Points to start tracking from * @param[in,out] points_cnt The amount of points and it returns the amount of points tracked * @param[in] half_window_size Half the window size (in both x and y direction) to search inside * @param[in] subpixel_factor The subpixel factor which calculations should be based on * @param[in] max_iterations Maximum amount of iterations to find the new point * @param[in] step_threshold The threshold of additional subpixel flow at which the iterations should stop * @param[in] max_points The maximum amount of points to track, we skip x points and then take a point. * @param[in] pyramid_level Level of pyramid used in computation (0 == no pyramids used) * @return The vectors from the original *points in subpixels * * Pyramidal implementation of Lucas-Kanade feature tracker. * * Uses input images to build pyramid of padded images. * <p>For every pyramid level:</p> * <p> For all points:</p> * - (1) determine the subpixel neighborhood in the old image * - (2) get the x- and y- gradients * - (3) determine the 'G'-matrix [sum(Axx) sum(Axy); sum(Axy) sum(Ayy)], where sum is over the window * - (4) iterate over taking steps in the image to minimize the error: * + [a] get the subpixel neighborhood in the new image * + [b] determine the image difference between the two neighborhoods * + [c] calculate the 'b'-vector * + [d] calculate the additional flow step and possibly terminate the iteration * - (5) use calculated flow as initial flow estimation for next level of pyramid */ struct flow_t *opticFlowLK(struct image_t *new_img, struct image_t *old_img, struct point_t *points, uint16_t *points_cnt, uint16_t half_window_size, uint16_t subpixel_factor, uint8_t max_iterations, uint8_t step_threshold, uint8_t max_points, uint8_t pyramid_level, uint8_t keep_bad_points) { // if no pyramids, use the old code: if (pyramid_level == 0) { // use the old code in this case: return opticFlowLK_flat(new_img, old_img, points, points_cnt, half_window_size, subpixel_factor, max_iterations, step_threshold, max_points, keep_bad_points); } // Allocate some memory for returning the vectors struct flow_t *vectors = malloc(sizeof(struct flow_t) * max_points); // Determine patch sizes and initialize neighborhoods uint16_t patch_size = 2 * half_window_size + 1; // TODO: Feature management shows that this threshold rejects corners maybe too often, maybe another formula could be chosen uint32_t error_threshold = (25 * 25) * (patch_size * patch_size); uint16_t padded_patch_size = patch_size + 2; uint16_t border_size = padded_patch_size / 2 + 2; // amount of padding added to images // Allocate memory for image pyramids struct image_t *pyramid_old = malloc(sizeof(struct image_t) * (pyramid_level + 1)); struct image_t *pyramid_new = malloc(sizeof(struct image_t) * (pyramid_level + 1)); // Build pyramid levels pyramid_build(old_img, pyramid_old, pyramid_level, border_size); pyramid_build(new_img, pyramid_new, pyramid_level, border_size); // Create the window images struct image_t window_I, window_J, window_DX, window_DY, window_diff; image_create(&window_I, padded_patch_size, padded_patch_size, IMAGE_GRAYSCALE); image_create(&window_J, patch_size, patch_size, IMAGE_GRAYSCALE); image_create(&window_DX, patch_size, patch_size, IMAGE_GRADIENT); image_create(&window_DY, patch_size, patch_size, IMAGE_GRADIENT); image_create(&window_diff, patch_size, patch_size, IMAGE_GRADIENT); // Iterate through pyramid levels for (int8_t LVL = pyramid_level; LVL != -1; LVL--) { uint16_t points_orig = *points_cnt; *points_cnt = 0; uint16_t new_p = 0; // Calculate the amount of points to skip float skip_points = (points_orig > max_points) ? (float)points_orig / max_points : 1; // Go through all points for (uint16_t i = 0; i < max_points && i < points_orig; i++) { uint16_t p = i * skip_points; if (LVL == pyramid_level) { // Convert point position on original image to a subpixel coordinate on the top pyramid level vectors[new_p].pos.x = (points[p].x * subpixel_factor) >> pyramid_level; vectors[new_p].pos.y = (points[p].y * subpixel_factor) >> pyramid_level; vectors[new_p].flow_x = 0; vectors[new_p].flow_y = 0; } else { // (5) use calculated flow as initial flow estimation for next level of pyramid vectors[new_p].pos.x = vectors[p].pos.x << 1; vectors[new_p].pos.y = vectors[p].pos.y << 1; vectors[new_p].flow_x = vectors[p].flow_x << 1; vectors[new_p].flow_y = vectors[p].flow_y << 1; } // If the pixel is outside original image, do not track it if ((((int32_t) vectors[new_p].pos.x + vectors[new_p].flow_x) < 0) || ((vectors[new_p].pos.x + vectors[new_p].flow_x) > (uint32_t)((pyramid_new[LVL].w - 1 - 2 * border_size)* subpixel_factor)) || (((int32_t) vectors[new_p].pos.y + vectors[new_p].flow_y) < 0) || ((vectors[new_p].pos.y + vectors[new_p].flow_y) > (uint32_t)((pyramid_new[LVL].h - 1 - 2 * border_size)* subpixel_factor))) { continue; } // (1) determine the subpixel neighborhood in the old image image_subpixel_window(&pyramid_old[LVL], &window_I, &vectors[new_p].pos, subpixel_factor, border_size); // (2) get the x- and y- gradients image_gradients(&window_I, &window_DX, &window_DY); // (3) determine the 'G'-matrix [sum(Axx) sum(Axy); sum(Axy) sum(Ayy)], where sum is over the window int32_t G[4]; image_calculate_g(&window_DX, &window_DY, G); // calculate G's determinant in subpixel units: int32_t Det = (G[0] * G[3] - G[1] * G[2]); // Check if the determinant is bigger than 1 if (Det < 1) { continue; } // (4) iterate over taking steps in the image to minimize the error: bool tracked = true; for (uint8_t it = max_iterations; it--;) { struct point_t new_point = { vectors[new_p].pos.x + vectors[new_p].flow_x, vectors[new_p].pos.y + vectors[new_p].flow_y, 0, 0, 0 }; // If the pixel is outside original image, do not track it if ((((int32_t)vectors[new_p].pos.x + vectors[new_p].flow_x) < 0) || (new_point.x > (uint32_t)((pyramid_new[LVL].w - 1 - 2 * border_size)*subpixel_factor)) || (((int32_t)vectors[new_p].pos.y + vectors[new_p].flow_y) < 0) || (new_point.y > (uint32_t)((pyramid_new[LVL].h - 1 - 2 * border_size)*subpixel_factor))) { tracked = false; break; } // [a] get the subpixel neighborhood in the new image image_subpixel_window(&pyramid_new[LVL], &window_J, &new_point, subpixel_factor, border_size); // [b] determine the image difference between the two neighborhoods uint32_t error = image_difference(&window_I, &window_J, &window_diff); if (error > error_threshold && it < max_iterations / 2) { tracked = false; break; } int32_t b_x = image_multiply(&window_diff, &window_DX, NULL) / 255; int32_t b_y = image_multiply(&window_diff, &window_DY, NULL) / 255; // [d] calculate the additional flow step and possibly terminate the iteration int16_t step_x = (((int64_t) G[3] * b_x - G[1] * b_y) * subpixel_factor) / Det; int16_t step_y = (((int64_t) G[0] * b_y - G[2] * b_x) * subpixel_factor) / Det; vectors[new_p].flow_x = vectors[new_p].flow_x + step_x; vectors[new_p].flow_y = vectors[new_p].flow_y + step_y; vectors[new_p].error = error; // Check if we exceeded the treshold CHANGED made this better for 0.03 if ((abs(step_x) + abs(step_y)) < step_threshold) { break; } } // lucas kanade step iteration // If we tracked the point we update the index and the count if (tracked) { new_p++; (*points_cnt)++; } else if (keep_bad_points) { vectors[new_p].pos.x = 0; vectors[new_p].pos.y = 0; vectors[new_p].flow_x = 0; vectors[new_p].flow_y = 0; vectors[new_p].error = LARGE_FLOW_ERROR; new_p++; (*points_cnt)++; } } // go through all points
int main(int argc, char *argv[]) { const int rows = 1000; const int cols = 1000; View3D view; Matrix vtm; Polygon side[4]; Polygon tpoly; Point tv[3]; Point v[4]; Color color[4]; Image *src; char filename[100]; double x; int i; // set some colors Color_set( &color[0], 0, 0, 1 ); Color_set( &color[1], 0, 1, 0 ); Color_set( &color[2], 1, 0, 0 ); Color_set( &color[3], 1, 0, 1 ); // initialize polygons for(i=0;i<4;i++) { polygon_init( &side[i] ); } // corners of a cube, centered at (0, 0, 0) point_set3D( &v[0], 0, 1, 0 ); point_set3D( &v[1], 1, -1, 0); point_set3D( &v[2], -1, -1, 0 ); point_set3D( &v[3], 0, 0, 1 ); //base of the pyramid polygon_set(&side[3], 3, &(v[0])); //side1 point_copy(&tv[0], &v[0]); point_copy(&tv[1], &v[2]); point_copy(&tv[2], &v[3]); polygon_set(&side[0], 3, tv); //side2 point_copy(&tv[0], &v[0]); point_copy(&tv[1], &v[1]); point_copy(&tv[2], &v[3]); polygon_set(&side[1], 3, tv); //side3 point_copy(&tv[0], &v[1]); point_copy(&tv[1], &v[2]); point_copy(&tv[2], &v[3]); polygon_set(&side[2], 3, tv); point_set3D( &(view.vrp), 1, 0, 0); vector_set( &(view.vpn), -view.vrp.val[0], -view.vrp.val[1], -view.vrp.val[2] ); vector_set( &(view.vup), 0, 0, 1 ); view.d = 1; // focal length view.du = 2; view.dv = view.du * (float)rows / cols; view.f = 0; // front clip plane view.b = 4; // back clip plane view.screenx = cols; view.screeny = rows; matrix_setView3D( &vtm, &view ); // use a temprary polygon to transform stuff polygon_init( &tpoly ); printf("Drawing pyramid\n"); x = -2; int j; for (j=0; j<50; j++){ // create image src = image_create( rows, cols ); point_set3D(&(view.vrp), x , 2, 0.5); vector_set( &(view.vpn), -x, -2, -0.5); matrix_setView3D(&vtm, &view); i=0; for(i=0;i<4;i++) { polygon_copy( &tpoly, &side[i] ); matrix_xformPolygon( &vtm, &tpoly ); // normalize by homogeneous coordinate before drawing polygon_normalize( &tpoly ); polygon_draw( &tpoly, src, color[i] ); //polygon_print( &tpoly, stdout ); } printf("Writing image\n"); sprintf(filename, "pyramid_%04d.ppm", j); image_write( src, filename); free(src); if(j<25){ x += 0.08; }else{ x -= 0.08; } } printf("Making the .gif file...\n"); system("convert -delay 10 pyramid_*.ppm ../images/ext1.gif"); system("rm -f pyramid*"); return(0); }
int main(int argc, char *argv[]) { Image *src; const int rows = 600; const int cols = 800; const int Resolution = 50; Color white; Color Grey; Color dkGrey; Color Red; Color Blue; Point unitCircle[Resolution]; Point unitSquare[4]; Point pt[Resolution]; Point ptt[Resolution]; int i, j, index = 0; Matrix VTM, GTM, LTM; Polygon *ship[50]; Color shipColor[50]; double theta = 0.0; double phaserAngle = 0.0; int firePhase = 0; color_set(&Grey, 180/255.0, 180/255.0, 183/255.0); color_set(&dkGrey, 140/255.0, 140/255.0, 143/255.0); color_set(&Red, 250/255.0, 40/255.0, 40/255.0); color_set(&Blue, 30/255.0, 20/255.0, 250/255.0); if(argc > 1) { theta = atoi(argv[1]); } printf("Drawing ship with orientation %.2f degrees\n", theta); if(argc > 2) { phaserAngle = atoi(argv[2]); firePhase = 1; printf("Drawing phaser with angle %.2f degrees\n", phaserAngle); } srand(42); src = image_create(rows, cols); color_set(&white, 1.0, 1.0, 1.0); for(i=0; i<rows; i++){ for(j=0; j<cols; j++){ if((rand()%50) == 13){ image_setColor(src, i, j, white); } } } // initialize the three matrices matrix_identity(&VTM); matrix_identity(>M); matrix_identity(<M); // Fix world coordinates as normal (x, y) // give the view window an origin at -180m, -150m // size is a 4x3 ratio // VTM = T(0, rows-1)S(cols/vx, rows/vy)T(180, 150) matrix_translate2D(&VTM, 120, 100); matrix_scale2D(&VTM, cols/(4*60), -rows/(3*60)); matrix_translate2D(&VTM, 0, rows-1); printf("VTM\n"); matrix_print(&VTM, stdout); // make a space ship oriented along the positive X axis // use the LTM to move simple primitives into place // use the GTM to rotate the ship // use the VTM to change the view // make a list of points that form the unit circle for(i=0;i<Resolution;i++) { point_set2D(&(unitCircle[i]), cos( i * 2.0 * M_PI / (float)Resolution), sin( i * 2.0 * M_PI / (float)Resolution)); } // set up the unit square point_set2D(&(unitSquare[0]), 0, 0); point_set2D(&(unitSquare[1]), 1, 0); point_set2D(&(unitSquare[2]), 1, 1); point_set2D(&(unitSquare[3]), 0, 1); // build a set of polygons that form the ship in model space // put the origin of the model between the engines // outline for the main disk matrix_identity(<M); matrix_scale2D(<M, 31, 31); // move it 20m along the X-axis matrix_translate2D(<M, 60, 0); // transform the circle points using LTM for(i=0;i<Resolution;i++) { matrix_xformPoint(<M, &(unitCircle[i]), &(pt[i])); } // add the polygon matrix_print(<M, stdout); ship[index] = polygon_createp(Resolution, pt); shipColor[index++] = Red; printf("Post-LTM\n"); polygon_print(ship[0], stdout); // main disk matrix_identity(<M); matrix_scale2D(<M, 30, 30); // move it 20m along the X-axis matrix_translate2D(<M, 60, 0); // transform the circle points using LTM for(i=0;i<Resolution;i++) { matrix_xformPoint(<M, &(unitCircle[i]), &(pt[i])); } // add the polygon matrix_print(<M, stdout); ship[index] = polygon_createp(Resolution, pt); shipColor[index++] = Grey; // central bridge disk matrix_identity(<M); matrix_scale2D(<M, 10, 10); // move it 20m along the X-axis matrix_translate2D(<M, 60, 0); // transform the circle points using LTM for(i=0;i<Resolution;i++) { matrix_xformPoint(<M, &(unitCircle[i]), &(pt[i])); } // add the polygon matrix_print(<M, stdout); ship[index] = polygon_createp(Resolution, pt); shipColor[index++] = dkGrey; // make the body disk elongated along the X axis matrix_identity(<M); matrix_scale2D(<M, 30, 12); matrix_translate2D(<M, 2.5, 0); // transform the circle points using LTM for(i=0;i<Resolution;i++) { matrix_xformPoint(<M, &(unitCircle[i]), &(pt[i])); } // add the polygon matrix_print(<M, stdout); ship[index] = polygon_createp(Resolution, pt); shipColor[index++] = Grey; // make a trapezoidal strut out of the unit square matrix_identity(<M); matrix_translate2D(<M, -0.5, 0.0); matrix_scale2D(<M, 10, 10); matrix_shear2D(<M, .2, 0.0); for(i=0;i<4;i++) { matrix_xformPoint(<M, &(unitSquare[i]), &(pt[i])); } // move the strut out from the origin along the Y axis matrix_identity(<M); matrix_translate2D(<M, 0, 12); for(i=0;i<4;i++) { matrix_xformPoint(<M, &(pt[i]), &(ptt[i])); } // add the polygon matrix_print(<M, stdout); ship[index] = polygon_createp(4, ptt); shipColor[index++] = Grey; // place the second strut matrix_identity(<M); matrix_scale2D(<M, 1, -1); matrix_translate2D(<M, 0, -12); for(i=0;i<4;i++) { matrix_xformPoint(<M, &(pt[i]), &(ptt[i])); } // add the polygon ship[index] = polygon_createp(4, ptt); shipColor[index++] = Grey; // create an engine outline from the unit circle matrix_identity(<M); matrix_scale2D(<M, 31, 6); // make the engine for(i=0;i<Resolution;i++) { matrix_xformPoint(<M, &(unitCircle[i]), &(pt[i])); } // send one engine to the right location matrix_identity(<M); matrix_translate2D(<M, -5, 27); // move the engine for(i=0;i<Resolution;i++) { matrix_xformPoint(<M, &(pt[i]), &(ptt[i])); } // add the polygon ship[index] = polygon_createp(Resolution, ptt); shipColor[index++] = Blue; // send the other engine to the right location matrix_identity(<M); matrix_translate2D(<M, -5, -27); // move the engine for(i=0;i<Resolution;i++) { matrix_xformPoint(<M, &(pt[i]), &(ptt[i])); } // add the polygon ship[index] = polygon_createp(Resolution, ptt); shipColor[index++] = Blue; // create an engine matrix_identity(<M); matrix_scale2D(<M, 30, 5); // make the engine for(i=0;i<Resolution;i++) { matrix_xformPoint(<M, &(unitCircle[i]), &(pt[i])); } // send one engine to the right location matrix_identity(<M); matrix_translate2D(<M, -5, 27); // move the engine for(i=0;i<Resolution;i++) { matrix_xformPoint(<M, &(pt[i]), &(ptt[i])); } // add the polygon ship[index] = polygon_createp(Resolution, ptt); shipColor[index++] = Grey; // send the other engine to the right location matrix_identity(<M); matrix_translate2D(<M, -5, -27); // move the engine for(i=0;i<Resolution;i++) { matrix_xformPoint(<M, &(pt[i]), &(ptt[i])); } // add the polygon ship[index] = polygon_createp(Resolution, ptt); shipColor[index++] = Grey; // set up the phaser if(firePhase) { matrix_identity(<M); matrix_scale2D(<M, 100, 2); // orient the phaser matrix_rotateZ(<M, cos(phaserAngle*M_PI/180.0), sin(phaserAngle*M_PI/180.0)); // translate it to the center of the disk and out matrix_translate2D(<M, 60 + 30 * cos(phaserAngle*M_PI/180.0), 30 * sin(phaserAngle*M_PI/180.0) ); // use the unit square for(i=0;i<4;i++) { matrix_xformPoint(<M, &(unitSquare[i]), &(pt[i])); } // add the polygon ship[index] = polygon_createp(4, pt); shipColor[index++] = Red; } matrix_rotateZ(>M, cos(theta*M_PI/180.0), sin(theta*M_PI/180.0)); printf("GTM:\n"); matrix_print(>M, stdout); printf("Pre-GTM/VTM\n"); polygon_print(ship[0], stdout); for(i=0;i<index;i++) { // multiply the polygon by the global transform matrix matrix_xformPolygon(>M, ship[i]); if(i==0) { printf("Pre-VTM\n"); polygon_print(ship[i], stdout); } // multiply the polygon by the view transformation matrix matrix_xformPolygon(&VTM, ship[i]); if(i==0) { printf("Pre-draw\n"); polygon_print(ship[i], stdout); } // draw the polygon polygon_drawFill(ship[i], src, shipColor[i]); } image_write(src, "space.ppm"); image_free(src); return(0); }
static void command_image_loadcreate(void) { mess_image *image; int device_type; int device_slot; const char *device_tag; int i, format_index = 0; const char *filename; const char *format; char buf[128]; const struct IODevice *dev; const char *file_extensions; device_slot = current_command->u.image_args.device_slot; device_type = current_command->u.image_args.device_type; device_tag = current_command->u.image_args.device_tag; /* look up the image slot */ if (device_tag) image = image_from_devtag_and_index(device_tag, device_slot); else image = image_from_devtype_and_index(device_type, device_slot); if (!image) { state = STATE_ABORTED; report_message(MSG_FAILURE, "Image slot '%s %i' does not exist", device_typename(device_type), device_slot); return; } dev = image_device(image); file_extensions = dev->file_extensions; /* is an image format specified? */ format = current_command->u.image_args.format; if (format) { if (current_command->command_type != MESSTEST_COMMAND_IMAGE_CREATE) { state = STATE_ABORTED; report_message(MSG_FAILURE, "Cannot specify format unless creating"); return; } if (!dev->createimage_options) { state = STATE_ABORTED; report_message(MSG_FAILURE, "Cannot specify format for device"); return; } for (i = 0; dev->createimage_options[i].name; i++) { if (!strcmp(format, dev->createimage_options[i].name)) break; } if (!dev->createimage_options[i].name) { state = STATE_ABORTED; report_message(MSG_FAILURE, "Unknown device '%s'", format); return; } format_index = i; file_extensions = dev->createimage_options[i].extensions; } /* figure out the filename */ filename = current_command->u.image_args.filename; if (!filename) { snprintf(buf, sizeof(buf) / sizeof(buf[0]), "%s.%s", current_testcase.name, file_extensions); make_filename_temporary(buf, sizeof(buf) / sizeof(buf[0])); filename = buf; } /* actually create or load the image */ switch(current_command->command_type) { case MESSTEST_COMMAND_IMAGE_CREATE: if (image_create(image, filename, format_index, NULL)) { state = STATE_ABORTED; report_message(MSG_FAILURE, "Failed to create image '%s': %s", filename, image_error(image)); return; } break; case MESSTEST_COMMAND_IMAGE_LOAD: if (image_load(image, filename)) { state = STATE_ABORTED; report_message(MSG_FAILURE, "Failed to load image '%s': %s", filename, image_error(image)); return; } break; default: break; } }
/* example main() function that takes several disk image filenames as * arguments on the command line. * Note that you'll need three images to test recovery after a failure. */ int main(int argc, char **argv) { printf("start\n"); /* create the underlying blkdevs from the images */ struct blkdev *d1 = image_create(argv[1]); struct blkdev *d2 = image_create(argv[2]); /* ... */ printf("created the underlying blkdevs from the images\n"); /* create the mirror */ struct blkdev *disks[] = {d1, d2}; struct blkdev *mirror = mirror_create(disks); printf("created the mirror\n"); /* two asserts - that the mirror create worked, and that the size * is correct. */ assert(mirror != NULL); printf("mirror create worked\n"); assert(mirror->ops->num_blocks(mirror) == d1->ops->num_blocks(d1)); printf("size is correct\n"); /* put your test code here. Errors should exit via either 'assert' * or 'exit(1)' - that way the shell script knows that the test failed. */ /* suggested test codes (from the assignment PDF) You should test that your code: - creates a volume properly - returns the correct length - can handle reads and writes of different sizes, and returns the same data as was written - reads data from the proper location in the images, and doesn't overwrite incorrect locations on write. - continues to read and write correctly after one of the disks fails. (call image_fail() on the image blkdev to force it to fail) - continues to read and write (correctly returning data written before the failure) after the disk is replaced. - reads and writes (returning data written before the first failure) after the other disk fails */ char src[BLOCK_SIZE * 16]; FILE *fp = fopen("/dev/urandom", "r"); assert(fread(src, sizeof(src), 1, fp) == 1); fclose(fp); printf("5\n"); printf("first test\n"); int i, result; for (i = 0; i < 128; i += 16) { result = mirror->ops->write(mirror, i, 16, src); assert(result == SUCCESS); } printf("second test\n"); char dst[BLOCK_SIZE * 16]; for (i = 0; i < 128; i += 16) { result = mirror->ops->read(mirror, i, 16, dst); assert(result == SUCCESS); assert(memcmp(src, dst, 16*BLOCK_SIZE) == 0); } printf("third test\n"); image_fail(d1); for (i = 0; i < 128; i += 16) { result = mirror->ops->read(mirror, i, 16, dst); assert(result == SUCCESS); assert(memcmp(src, dst, 16*BLOCK_SIZE) == 0); } printf("fourth test\n"); struct blkdev *d3 = image_create(argv[3]); assert(mirror_replace(mirror, 0, d3) == SUCCESS); for (i = 0; i < 128; i += 16) { result = mirror->ops->read(mirror, i, 16, dst); assert(result == SUCCESS); assert(memcmp(src, dst, 16*BLOCK_SIZE) == 0); } printf("Mirror Test: SUCCESS\n"); return 0; }
int main(int argc, char* argv[]) { int opt = 0; struct sfs_options sfs_opts; /* Service variables */ size_t rsrvd_size = MBR_SIZE; size_t index_size = 0; size_t block_size = 0; size_t total_blocks = 0; size_t index_sz_perblk = 0; off_t file_size = 0; char* index_size_s = NULL; char* block_size_s = NULL; char* label = NULL; /* Struct for getopt_long */ static struct option const long_options[] = { {"help", no_argument, NULL, 'h'}, {"metadata", required_argument, NULL, 'm'}, {"block-size", required_argument, NULL, 'b'}, {"label", required_argument, NULL, 'l'}, {"version", no_argument, NULL, 'v'}, {NULL, 0, NULL, 0} }; if (argc == 1) { fprintf(stderr, "No parameters.\n"); usage(EXIT_FAILURE); } /* Get user options */ while ((opt = getopt_long(argc - 1, argv, "hm:b:l:", long_options, NULL)) != -1) { switch (opt) { case 'h': usage(EXIT_SUCCESS); break; case 'm': index_size_s = optarg; break; case 'b': block_size_s = optarg; break; case 'l': label = optarg; break; case 'v': usage(EXIT_SUCCESS); break; default: usage(EXIT_FAILURE); } } /* * Try to open file */ int fd = open(argv[argc - 1], O_RDWR); if (fd == -1 && argc == 2) usage(EXIT_SUCCESS); if (fd == -1) { fprintf(stderr, "Invalid input file/device.\n"); usage(EXIT_INPFILE); } /* * File size calculate and check it */ file_size = lseek(fd, 0, SEEK_END); close(fd); if (file_size < (MBR_SIZE + INDEX_MIN_SIZE)) { fprintf(stderr, "Too small file size.\n"); fprintf(stderr, "%s %luB\n", "The smallest file size is", MBR_SIZE + INDEX_MIN_SIZE); exit(EXIT_FILELRG); } /* * Handler blocksize data */ if (block_size_s == NULL) block_size = DEFAULT_BLOCK_SIZE; else { block_size = convert_size(block_size_s, 0); /* block size must be greater than 128B */ if (block_size <= DEFAULT_MIN_BLOCK/2 || errno == EINVAL) { fprintf(stderr, "Invalid block size.\n"); usage(EXIT_NOBS); } long int divisor = DEFAULT_MIN_BLOCK; /* Check on the power of two */ while (divisor > 0 && (divisor != block_size)) divisor <<= 1; if (divisor < 0) { fprintf(stderr, "Block size isn't the power of 2.\n"); usage(EXIT_BSDGR2); } } if (block_size > file_size) { fprintf(stderr, "Block size more than file size.\n"); usage(EXIT_BSLRG); } if (file_size % block_size != 0) { fprintf(stderr, "Block size isn't a divisor of data size.\n"); usage(EXIT_BSDIV); } /* * Calculate reserved area size in bytes */ if (block_size <= MBR_SIZE) rsrvd_size = MBR_SIZE; else rsrvd_size = block_size; /* * Handler index size */ if (index_size_s == NULL) { double buf = DEFAULT_INDEX_PERCENT * file_size / 100L; index_size = (size_t)round(buf); } else { index_size = convert_size(index_size_s, file_size); if (index_size == 0 || errno == EINVAL) { fprintf(stderr, "Invalid metadata size.\n"); usage(EXIT_NOMD); } } /* Auto align to BLOCK_SIZE (up) */ if (index_size % block_size != 0) index_size += block_size - index_size % block_size; /* Check index size(maybe file size too small) */ if (index_size > (file_size - rsrvd_size)) { fprintf(stderr, "Index area size more or equal than file" " size.\n"); usage(EXIT_MDLRG); } /* Check size of index area */ if (index_size < INDEX_MIN_SIZE) { fprintf(stderr, "Index part size too small.\n"); usage(EXIT_MDSML); } /* * Handler label name */ unsigned length = 0; int i = 0; if (label != NULL && (length = strlen(label)) >= VOLUME_NAME_SIZE) { fprintf(stderr, "%s %ld %s", "Label shouldn't be longer" " than ", VOLUME_NAME_SIZE - 1, " symbols.\n"); usage(EXIT_LBL); } /* Check on unsupported symbols */ for (i = 0; i < length; i++) if (label[i] < 0x20 || (label[i] >= 0x80 && label[i] <= 0x9F) || label[i] == '"' || label[i] == '*' || label[i] == ':' || label[i] == '<' || label[i] == '>' || label[i] == '?' || label[i] == '\\' || label[i] == 0x5C || label[i] == 0x7F || label[i] == 0xA0) { fprintf(stderr, "Unsupported symbol \'%c\' " "in volume name.\n", label[i]); usage(EXIT_LBL); } /* * Start to flll fields of options struct */ total_blocks = file_size / block_size; /* Convert reserved area size to size in blocks */ rsrvd_size /= block_size; /* Convert index area size to align size per block size */ if (index_size % block_size == 0) index_sz_perblk = index_size / block_size; else index_sz_perblk = index_size / block_size + 1; /* Fill struct */ sfs_opts.time_stamp = time(NULL); sfs_opts.data_size = total_blocks - rsrvd_size - index_sz_perblk; sfs_opts.index_size = index_size; sfs_opts.total_block = total_blocks; sfs_opts.reserved_size = rsrvd_size; sfs_opts.block_size = (size_t)log2(block_size) - BEGIN_POWER_OF_BS; if (label != NULL) strcpy(sfs_opts.label, label); else sfs_opts.label[0] = '\0'; sfs_opts.file_name = (char*) calloc((strlen(argv[argc - 1]) + 1), sizeof(char)); strcpy(sfs_opts.file_name, argv[argc - 1]); /* * Create empty SFS image */ if (image_create(sfs_opts) != 0) { free(sfs_opts.file_name); return EXIT_FAILURE; } free(sfs_opts.file_name); return EXIT_SUCCESS; }
static bool test_simple_errors(GLenum src_target, GLenum dst_target) { bool pass = true; GLuint i, src, src2, dst; src = image_create(src_target); dst = image_create(dst_target); /* Test all three combinations of incomplete src or dst */ glCopyImageSubData(src, src_target, 0, 0, 0, 0, dst, dst_target, 0, 0, 0, 0, 0, 0, 0); pass &= piglit_check_gl_error(GL_INVALID_OPERATION); image_storage(src_target, src, GL_RGBA8, 32, 32); assert(piglit_check_gl_error(GL_NO_ERROR)); glCopyImageSubData(src, src_target, 0, 0, 0, 0, dst, dst_target, 0, 0, 0, 0, 0, 0, 0); pass &= piglit_check_gl_error(GL_INVALID_OPERATION); image_storage(dst_target, dst, GL_RGBA8, 32, 32); assert(piglit_check_gl_error(GL_NO_ERROR)); /* We want to test with empty src but valid dst */ src2 = image_create(src_target); glCopyImageSubData(src2, src_target, 0, 0, 0, 0, dst, dst_target, 0, 0, 0, 0, 0, 0, 0); pass &= piglit_check_gl_error(GL_INVALID_OPERATION); /* This is no longer needed */ image_delete(src_target, src2); /* Section 18.3.2 (Copying Between Images) of the OpenGL 4.5 Core * Profile spec says: * * "An INVALID_VALUE error is generated if either name does not * correspond to a valid renderbuffer or texture object according * to the corresponding target parameter." */ if (src_target != GL_RENDERBUFFER_EXT) { for (i = 0; i < ARRAY_LENGTH(targets); ++i) { if (targets[i] == src_target) continue; /* here, targets[i] doesn't match src object's target */ glCopyImageSubData(src, targets[i], 0, 0, 0, 0, dst, dst_target, 0, 0, 0, 0, 0, 0, 0); pass &= piglit_check_gl_error(GL_INVALID_VALUE); if (!pass) return false; } } /* Section 18.3.2 (Copying Between Images) of the OpenGL 4.5 Core * Profile spec says: * * "An INVALID_VALUE error is generated if either name does not * correspond to a valid renderbuffer or texture object according * to the corresponding target parameter." */ if (dst_target != GL_RENDERBUFFER_EXT) { for (i = 0; i < ARRAY_LENGTH(targets); ++i) { if (targets[i] == dst_target) continue; /* here, targets[i] doesn't match dst object's target */ glCopyImageSubData(src, src_target, 0, 0, 0, 0, dst, targets[i], 0, 0, 0, 0, 0, 0, 0); pass &= piglit_check_gl_error(GL_INVALID_VALUE); if (!pass) return false; } } /* 4523 should be a bogus renderbuffer/texture */ glCopyImageSubData(4523, src_target, 0, 0, 0, 0, dst, dst_target, 0, 0, 0, 0, 0, 0, 0); pass &= piglit_check_gl_error(GL_INVALID_VALUE); glCopyImageSubData(src, src_target, 0, 0, 0, 0, 4523, dst_target, 0, 0, 0, 0, 0, 0, 0); pass &= piglit_check_gl_error(GL_INVALID_VALUE); /* Invalid level */ glCopyImageSubData(src, src_target, 5, 0, 0, 0, dst, dst_target, 0, 0, 0, 0, 0, 0, 0); pass &= piglit_check_gl_error(GL_INVALID_VALUE); glCopyImageSubData(src, src_target, 0, 0, 0, 0, dst, dst_target, 5, 0, 0, 0, 0, 0, 0); pass &= piglit_check_gl_error(GL_INVALID_VALUE); /* Region out of bounds */ glCopyImageSubData(src, src_target, 0, 7, 5, 2, dst, dst_target, 0, 0, 0, 0, 26, 25, 20); pass &= piglit_check_gl_error(GL_INVALID_VALUE); glCopyImageSubData(src, src_target, 0, 7, 5, 2, dst, dst_target, 0, 0, 0, 0, 25, 30, 20); pass &= piglit_check_gl_error(GL_INVALID_VALUE); glCopyImageSubData(src, src_target, 0, 7, 5, 2, dst, dst_target, 0, 0, 0, 0, 25, 24, 31); pass &= piglit_check_gl_error(GL_INVALID_VALUE); glCopyImageSubData(src, src_target, 0, 0, 0, 0, dst, dst_target, 0, 7, 5, 2, 26, 25, 20); pass &= piglit_check_gl_error(GL_INVALID_VALUE); glCopyImageSubData(src, src_target, 0, 0, 0, 0, dst, dst_target, 0, 7, 5, 2, 25, 30, 20); pass &= piglit_check_gl_error(GL_INVALID_VALUE); glCopyImageSubData(src, src_target, 0, 0, 0, 0, dst, dst_target, 0, 7, 5, 2, 25, 24, 31); pass &= piglit_check_gl_error(GL_INVALID_VALUE); image_delete(src_target, src); image_delete(dst_target, dst); return pass; }
//image conv image_p image_conv(image_p src, int dtype) { image_p dst; uint32_t i,j; uint32_t *src32, *dst32; uint16_t *src16, *dst16; uint8_t r,g,b,a; if(src->dtype == (uint32_t)dtype) return image_clone(src); CHECK_AND_UNSWIZZLE(src); dst = image_create(src->w, src->h, dtype); src32 = (uint32_t*)src->data; dst32 = (uint32_t*)dst->data; src16 = (uint16_t*)src->data; dst16 = (uint16_t*)dst->data; for(i = 0; i < src->h; i++) { for (j = 0; j<src->w; j++) { if(dtype == DISPLAY_PIXEL_FORMAT_8888){ if(src->dtype == DISPLAY_PIXEL_FORMAT_4444){ GET_RGBA_4444(src16[i*src->texw+j],r,g,b,a); dst32[i*dst->texw+j] = MAKE_RGBA_8888(r,g,b,a); } else if(src->dtype == DISPLAY_PIXEL_FORMAT_5551){ GET_RGBA_5551(src16[i*src->texw+j],r,g,b,a); dst32[i*dst->texw+j] = MAKE_RGBA_8888(r,g,b,a); } else if(src->dtype == DISPLAY_PIXEL_FORMAT_565){ GET_RGBA_565(src16[i*src->texw+j],r,g,b,a); dst32[i*dst->texw+j] = MAKE_RGBA_8888(r,g,b,a); } } else if(dtype == DISPLAY_PIXEL_FORMAT_4444){ if(src->dtype == DISPLAY_PIXEL_FORMAT_8888){ GET_RGBA_8888(src32[i*src->texw+j],r,g,b,a); dst16[i*dst->texw+j] = MAKE_RGBA_4444(r,g,b,a); } else if(src->dtype == DISPLAY_PIXEL_FORMAT_5551){ GET_RGBA_5551(src16[i*src->texw+j],r,g,b,a); dst16[i*dst->texw+j] = MAKE_RGBA_4444(r,g,b,a); } else if(src->dtype == DISPLAY_PIXEL_FORMAT_565){ GET_RGBA_565(src16[i*src->texw+j],r,g,b,a); dst16[i*dst->texw+j] = MAKE_RGBA_4444(r,g,b,a); } } else if(dtype == DISPLAY_PIXEL_FORMAT_5551){ if(src->dtype == DISPLAY_PIXEL_FORMAT_8888){ GET_RGBA_8888(src32[i*src->texw+j],r,g,b,a); dst16[i*dst->texw+j] = MAKE_RGBA_5551(r,g,b,a); } else if(src->dtype == DISPLAY_PIXEL_FORMAT_4444){ GET_RGBA_4444(src16[i*src->texw+j],r,g,b,a); dst16[i*dst->texw+j] = MAKE_RGBA_5551(r,g,b,a); } else if(src->dtype == DISPLAY_PIXEL_FORMAT_565){ GET_RGBA_565(src16[i*src->texw+j],r,g,b,a); dst16[i*dst->texw+j] = MAKE_RGBA_5551(r,g,b,a); } } else if(dtype == DISPLAY_PIXEL_FORMAT_565){ if(src->dtype == DISPLAY_PIXEL_FORMAT_8888){ GET_RGBA_8888(src32[i*src->texh+j],r,g,b,a); dst16[i*dst->texh+j] = MAKE_RGBA_565(r,g,b,a); } else if(src->dtype == DISPLAY_PIXEL_FORMAT_4444){ GET_RGBA_4444(src16[i*src->texh+j],r,g,b,a); dst16[i*dst->texh+j] = MAKE_RGBA_565(r,g,b,a); } else if(src->dtype == DISPLAY_PIXEL_FORMAT_5551){ GET_RGBA_5551(src16[i*src->texh+j],r,g,b,a); dst16[i*dst->texh+j] = MAKE_RGBA_565(r,g,b,a); } } } } dst->swizzle = 1; swizzle_swap(dst); CHECK_AND_SWIZZLE(src); return dst; }