void load_text(void) { //imageloader.c has already loaded 1 copy of a white coloured font //clone the image for each of our font colours, then set the white to that font //let imageloader dispose of the original images, and make sure we dipose of ours in the dispose function textColor = WhiteText; for (int i = 0; i < NUM_CHAR_IMAGES; i++) { for (int c = 0; c < NUM_FONTS; c++) { char_fonts[c][i] = clone_image(get_char_images()[i]); set_fontimage_color(char_fonts[c][i], c); } } for (int i = 0; i < NUM_NUM_IMAGES; i++) { for (int c = 0; c < NUM_FONTS; c++) { num_fonts[c][i] = clone_image(get_num_images()[i]); set_fontimage_color(num_fonts[c][i], c); } } for (int i = 0; i < NUM_SPEC_IMAGES; i++) { for (int c = 0; c < NUM_FONTS; c++) { spec_fonts[c][i] = clone_image(get_spec_images()[i]); set_fontimage_color(spec_fonts[c][i], c); } } }
image* median (image* src, matrix* factors) { image* dst = clone_image (src); rdword *prVals; long pos, xoff, nMtxHsX, nMtxHsY, nMtxSq, iMtxOff, iValued, iOX, iOY, iOYr; invalidn (factors->dimx >= 1 && factors->dimx < src->dimx / 4); invalidn (factors->dimy >= 1 && factors->dimy < src->dimy / 4); nMtxHsX = (factors->dimx - 1) / 2; nMtxHsY = (factors->dimy - 1) / 2; nMtxSq = factors->dimx * factors->dimy; iMtxOff = - (nMtxHsY * src->dimx + nMtxHsX); notnulln (prVals = new rdword[nMtxSq]); for (pos = 0; pos < dst->xyz; pos++) { xoff = 0; iValued = 0; for (iOY = -nMtxHsY; iOY <= nMtxHsY; ++iOY) { iOYr = iOY * src->dimx; if (pos + iOYr < 0 || pos + iOYr >= dst->xyz) continue; for (iOX = -nMtxHsX; iOX <= nMtxHsX; ++iOX, xoff++) { if (factors->factors[xoff] == 0) continue; if (pos + iOX + iOYr < 0 || pos + iOX + iOYr >= dst->xyz || int ((pos + iOX) / src->dimx) != int (pos / src->dimx)) continue; prVals[iValued++] = data(src)[pos + iOX + iOYr] * factors->factors[xoff]; } } if (iValued == 0) data(dst)[pos] = data(src)[pos]; else { qsort (prVals, iValued, sizeof (rdword), cmpr); data(dst)[pos] = prVals[iValued / 2]; } } return (dst); }
image* maxflt (image* src, matrix* factors) { image* dst = clone_image (src); rdword val; long pos, xoff, nMtxHsX, nMtxHsY, nMtxSq, iMtxOff, iValued, iOX, iOY, iOYr; invalidn (factors->dimx >= 1 && factors->dimx < src->dimx / 4); invalidn (factors->dimy >= 1 && factors->dimy < src->dimy / 4); nMtxHsX = (factors->dimx - 1) / 2; nMtxHsY = (factors->dimy - 1) / 2; nMtxSq = factors->dimx * factors->dimy; iMtxOff = - (nMtxHsY * src->dimx + nMtxHsX); for (pos = 0; pos < dst->xyz; pos++) { xoff = 0; val = -MAX_DOUBLE; iValued = 0; for (iOY = -nMtxHsY; iOY <= nMtxHsY; ++iOY) { iOYr = iOY * src->dimx; if (pos + iOYr < 0 || pos + iOYr >= dst->xyz) continue; for (iOX = -nMtxHsX; iOX <= nMtxHsX; ++iOX, xoff++) { if (factors->factors[xoff] == 0) continue; if (pos + iOX + iOYr < 0 || pos + iOX + iOYr >= dst->xyz || int ((pos + iOX) / src->dimx) != int (pos / src->dimx)) continue; iValued++; val = max (data(src)[pos + iOX + iOYr] * 1. / factors->factors[xoff], (rtbyte)val); } } if (iValued > 0) data(dst)[pos] = val; else data(dst)[pos] = data(src)[pos]; } return (dst); }
image_t * get_next_frame (bool_t store_wfa, int enlarge_factor, int smoothing, const char *reference_frame, format_e format, video_t *video, dectimer_t *timer, wfa_t *orig_wfa, bitfile_t *input) /* * Get next frame of the WFA 'video' from stream 'input'. * 'orig_wfa' is the constant part of the WFA used by all frames. * Depending on values of 'enlarge_factor' and 'smoothing' enlarge and * smooth image, respectively. * If 'store_wfa' is TRUE, then store WFA structure of reference frames * (used by analysis tool xwfa). * If 'reference_frame' is not NULL, then load image 'reference_frame' * from disk. * 'format' gives the color format to be used (either 4:2:0 or 4:4:4). * If 'timer' is not NULL, then accumulate running time statistics. * * Return value: * pointer to decoded frame * * Side effects: * 'video' and 'timer' struct are modified. */ { image_t *frame = NULL; /* current frame */ image_t *sframe = NULL; /* current smoothed frame */ bool_t current_frame_is_future_frame = NO; if (video->future_display == video->display) { /* * Future frame is already computed since it has been used * as reference frame. So just return the stored frame. */ if (video->frame) /* discard current frame */ free_image (video->frame); video->frame = video->future; video->future = NULL; if (video->sframe) /* discard current (smoothed) frame */ free_image (video->sframe); video->sframe = video->sfuture; video->sfuture = NULL; if (store_wfa) copy_wfa (video->wfa, video->wfa_future); video->display++; if (!store_wfa) video->wfa = NULL; } else { do /* compute next frame(s) */ { unsigned frame_number; /* current frame number */ clock_t ptimer; unsigned int stop_timer [3]; wfa_t *tmp_wfa = NULL; if (!store_wfa) video->wfa = orig_wfa; else { tmp_wfa = alloc_wfa (NO); copy_wfa (tmp_wfa, video->wfa); copy_wfa (video->wfa, orig_wfa); } /* * First step: read WFA from disk */ prg_timer (&ptimer, START); frame_number = read_next_wfa (video->wfa, input); stop_timer [0] = prg_timer (&ptimer, STOP); if (timer) { timer->input [video->wfa->frame_type] += stop_timer [0]; timer->frames [video->wfa->frame_type]++; } /* * Read reference frame from disk if required * (i.e., 1st frame is of type B or P) */ if (video->display == 0 && video->wfa->frame_type != I_FRAME) { if (!reference_frame) error ("First frame is %c-frame but no " "reference frame is given.", video->wfa->frame_type == B_FRAME ? 'B' : 'P'); video->frame = read_image_file (reference_frame); video->sframe = NULL; } /* * Depending on current frame type update past and future frames */ if (video->wfa->frame_type == I_FRAME) { if (video->past) /* discard past frame */ free_image (video->past); video->past = NULL; if (video->future) /* discard future frame */ free_image (video->future); video->future = NULL; if (video->sfuture) /* discard (smoothed) future frame */ free_image (video->sfuture); video->sfuture = NULL; if (video->frame) /* discard current frame */ free_image (video->frame); video->frame = NULL; if (video->sframe) /* discard current (smoothed) frame */ free_image (video->sframe); video->sframe = NULL; } else if (video->wfa->frame_type == P_FRAME) { if (video->past) /* discard past frame */ free_image (video->past); video->past = video->frame; /* past <- current frame */ video->frame = NULL; if (video->sframe) /* discard current (smoothed) frame */ free_image (video->sframe); video->sframe = NULL; if (store_wfa) copy_wfa (video->wfa_past, tmp_wfa); if (video->future) /* discard future frame */ free_image (video->future); video->future = NULL; if (video->sfuture) /* discard (smoothed) future frame */ free_image (video->sfuture); video->sfuture = NULL; } else /* B_FRAME */ { if (current_frame_is_future_frame) { if (video->future) /* discard future frame */ free_image (video->future); video->future = frame; /* future <- current frame */ if (video->sfuture) /* discard (smoothed) future frame */ free_image (video->sfuture); video->sfuture = sframe; /* future <- current (smoothed) */ if (store_wfa) copy_wfa (video->wfa_future, tmp_wfa); if (video->frame) /* discard current frame */ free_image (video->frame); video->frame = NULL; if (video->sframe) /* discard current (smoothed) frame */ free_image (video->sframe); video->sframe = NULL; frame = NULL; sframe = NULL; } else { if (video->wfa->wfainfo->B_as_past_ref == YES) { if (video->past) /* discard past frame */ free_image (video->past); video->past = video->frame; /* past <- current frame */ video->frame = NULL; if (video->sframe) /* discard current (smoothed) frame */ free_image (video->sframe); video->sframe = NULL; if (store_wfa) copy_wfa (video->wfa_past, tmp_wfa); } else { if (video->frame) /* discard current */ free_image (video->frame); video->frame = NULL; if (video->sframe) /* discard current (smoothed) frame */ free_image (video->sframe); video->sframe = NULL; } } } if (tmp_wfa) free_wfa (tmp_wfa); current_frame_is_future_frame = NO; /* * Second step: decode image * Optionally enlarge image if specified by option 'enlarge_factor'. */ { unsigned orig_width, orig_height; stop_timer [0] = stop_timer [1] = stop_timer [2] = 0; enlarge_image (enlarge_factor, format, (video->wfa->wfainfo->color && format == FORMAT_4_2_0) ? video->wfa->tree [video->wfa->tree [video->wfa->root_state][0]][0] : -1, video->wfa); if (enlarge_factor > 0) { orig_width = video->wfa->wfainfo->width << enlarge_factor; orig_height = video->wfa->wfainfo->height << enlarge_factor; } else { orig_width = video->wfa->wfainfo->width >> - enlarge_factor; orig_height = video->wfa->wfainfo->height >> - enlarge_factor; if (orig_width & 1) orig_width++; if (orig_height & 1) orig_height++; } frame = decode_image (orig_width, orig_height, format, timer != NULL ? stop_timer : NULL, video->wfa); if (timer) { timer->preprocessing [video->wfa->frame_type] += stop_timer [0]; timer->decoder [video->wfa->frame_type] += stop_timer [1]; timer->cleanup [video->wfa->frame_type] += stop_timer [2]; } } /* * Third step: restore motion compensation */ if (video->wfa->frame_type != I_FRAME) { prg_timer (&ptimer, START); restore_mc (enlarge_factor, frame, video->past, video->future, video->wfa); stop_timer [0] = prg_timer (&ptimer, STOP); if (timer) timer->motion [video->wfa->frame_type] += stop_timer [0]; } /* * Fourth step: smooth image along partitioning borders */ prg_timer (&ptimer, START); if (smoothing < 0) /* smoothing not changed by user */ smoothing = video->wfa->wfainfo->smoothing; if (smoothing > 0 && smoothing <= 100) { sframe = clone_image (frame); smooth_image (smoothing, video->wfa, sframe); } else sframe = NULL; stop_timer [0] = prg_timer (&ptimer, STOP); if (timer) timer->smooth [video->wfa->frame_type] += stop_timer [0]; if (frame_number == video->display) { video->display++; video->frame = frame; video->sframe = sframe; frame = NULL; sframe = NULL; } else if (frame_number > video->display) { video->future_display = frame_number; current_frame_is_future_frame = YES; } if (!store_wfa) remove_states (video->wfa->basis_states, video->wfa); } while (!video->frame); if (!store_wfa) video->wfa = NULL; } return video->sframe ? video->sframe : video->frame; }
int main(int argc, char *argv[]) { sequence *seq; /* pointer to input sequence data structure */ image **imgs; /* pointer to input sequence array of images */ image *out; /* pointer the output image */ char seq_in[100], /* input sequence name */ seq_out[100], /* output sequence name */ file_out[100]; /* output file name */ int length; /* length of the sequence */ int i; /* loop index */ /* Process input arguments */ if(argc != 3) { fprintf(stderr,"Usage: %s [input PGM sequence name] [output PGM sequence name]\n", argv[0]); exit(0); } else { strcpy(seq_in, argv[1]); strcpy(seq_out, argv[2]); } /* Load the input sequence */ seq = load_sequence(seq_in); /* Get a pointer to the sequence images */ imgs = get_sequence_images(seq); /* Get sequence length */ length = get_sequence_length(seq); /* Check if sequence is long enough */ if(length < 2) { fprintf(stderr, "sequence is too short\n"); exit(1); } /* Clone the first image to store results */ out = clone_image(imgs[0]); /* Loop through the sequence and write the mean sequence */ /* i.e. for each image of the input sequence, write the image */ /* resulting from the mean between the current image and */ /* the next one. */ for(i = 0; i < length - 1; i++) { /* Compute the mean between the current picture and the next one */ mean_image(imgs[i], imgs[i+1], out); /* Now write out the output image */ sprintf(file_out, "%s%03d.pgm", seq_out, i); printf("Writing out %s\n",file_out); pgm_write_image(out, file_out); } /* We must deallocate the memory the sequence and for the image before */ /* we finish */ free_image(out); free_sequence(seq); return(EXIT_SUCCESS); }
void calculate_difference_images(Image *source_image1, Image *source_image2, int n, Image *dest_image) { for (int i = 0; i < n; i++) { int h = source_image1[i].height; if (source_image2[i].height < h) h = source_image2[i].height; int w = source_image1[i].width; if (source_image2[i].width < w) w = source_image2[i].width; dest_image[i] = source_image1[i]; // Copy fields. dest_image[i].pixels = (unsigned int *)malloc(h * source_image1[i].extended_width * 4); Image *source1; int source1_is_cloned = 0; Image cloned_image1; if (source_image1[i].is_half_float) { dest_image[i].is_half_float = 0; dest_image[i].bits_per_component = 8; clone_image(&source_image1[i], &cloned_image1); convert_image_from_half_float(&cloned_image1, dynamic_range_min, dynamic_range_max, dynamic_range_gamma); convert_image_to_or_from_cairo_format(&cloned_image1); source1 = &cloned_image1; source1_is_cloned = 1; } else source1 = &source_image1[i]; Image *source2; int source2_is_cloned = 0; Image cloned_image2; if (source_image2[i].is_half_float) { clone_image(&source_image2[i], &cloned_image2); convert_image_from_half_float(&cloned_image2, dynamic_range_min, dynamic_range_max, dynamic_range_gamma); convert_image_to_or_from_cairo_format(&cloned_image2); source2 = &cloned_image2; source2_is_cloned = 1; } else source2 = &source_image2[i]; bool have_alpha = source1->alpha_bits > 0 && source2->alpha_bits > 0; for (int y = 0; y < h; y++) for (int x = 0; x < w; x++) { uint32_t pixel1 = source1->pixels[y * source1->extended_width + x]; uint32_t pixel2 = source2->pixels[y * source2->extended_width + x]; int difference = 0; bool add_rgb_diff = true; if (have_alpha) { int a1 = pixel_get_a(pixel1); int a2 = pixel_get_a(pixel2); if ((a1 | a2) == 0) add_rgb_diff = false; else difference += abs(a1 - a2); } else add_rgb_diff = true; if (add_rgb_diff) difference += abs(pixel_get_r(pixel1) - pixel_get_r(pixel2)) + abs(pixel_get_g(pixel1) - pixel_get_g(pixel2)) + abs(pixel_get_b(pixel1) - pixel_get_b(pixel2)); if (difference > 255) difference = 255; dest_image[i].pixels[y * dest_image[i].extended_width + x] = pack_rgb_alpha_0xff(difference, difference, difference); } if (source1_is_cloned) destroy_image(source1); if (source2_is_cloned) destroy_image(source2); } }