#include "c4d_general.h" #include "c4d_memory.h" #include "c4d_gui.h" #include "x4d_filter.h" #include "c4d_bitmapfilter.h" #include "filterpreview.h" #include "matrixutil.h" #include "matrixwrapper.h" #include "linefetchutil.h" Int32 do_matrix_effect_1dt(BM_REF bm, BM_TILE* dt, MATRIX_REF _emr, Int32 tile_flags) { RECT32 bounds; UChar* dst = nullptr; Int32 x1, y1, x2, y2; Int32 width; Int32 y; UChar* src_rows[MAXTRIX_MAX_COLUMNS]; Int32 err = FILTER_OK; ROW_REF src_rr; Int32 x_offset; Int32 y_offset; Int32 no_columns; Int32 no_rows; bounds = *(RECT32*) &dt->xmin; x1 = bounds.x1; y1 = bounds.y1; x2 = bounds.x2; y2 = bounds.y2; dst = (UChar*) dt->addr; width = bounds.x2 - bounds.x1; // width of the selected area get_effect_matrix_info(_emr, &no_columns, &no_rows, &x_offset, &y_offset); if ((src_rr = new_row_fetcher(bm, x1 - x_offset, x2 + (no_columns - x_offset - 1), tile_flags, TILE_BM_READ_ONLY, 0)) != 0) { Int32 j; for (j = 0; j < no_rows - 1; j++) { src_rows[j] = rf_get_bitmap_row(src_rr, y1 - y_offset + j); if (src_rows[j] == 0L) // unable to access this line? { delete_row_fetcher(src_rr, true); // free all buffered lines return FILTER_MEM_ERR; } } for (y = y1; y < y2; y++) { j = no_rows - 1; src_rows[j] = rf_get_bitmap_row(src_rr, y + (j - y_offset)); // ask for the next line if (src_rows[j] == 0L) // unable to access this line? { err = FILTER_MEM_ERR; break; } apply_matrix_effect(_emr, (void**) src_rows, dst, width); // apply the matrix function to the current destination line rf_free_bitmap_row(src_rr, y - y_offset); // we don't need this line for the next loop for (j = 1; j < no_rows; j++) // swap the source line pointers src_rows[j - 1] = src_rows[j]; dst += dt->width; // next destination line } delete_row_fetcher(src_rr, true); // free all buffered lines } return err; } Int32 do_matrix_effect(BM_REF bm, MATRIX_REF _emr, BaseThread* thread, Int32 tile_flags, Bool update_view, String* apply_filter_str) { BM_TILE* dt; RECT32 bounds; UChar* dst = nullptr; Int32 x1, y1, x2, y2; Int32 width, height; Int32 y; UChar* src_rows[MAXTRIX_MAX_COLUMNS]; Int32 err = FILTER_OK; ROW_REF src_rr; Int32 x_offset; Int32 y_offset; Int32 no_columns; Int32 no_rows; PROGRESS_ID pid = 0; Int32 progress_cnt; Int32 progress_max; x1 = bm->mask_rect.x1; y1 = bm->mask_rect.y1; x2 = bm->mask_rect.x2; y2 = bm->mask_rect.y2; width = bm->mask_rect.x2 - bm->mask_rect.x1; // width of the selected area height = bm->mask_rect.y2 - bm->mask_rect.y1; // height of the selected area progress_cnt = 0; progress_max = (height + bm->preferred_tile_height - 1) / bm->preferred_tile_height; pid = BfProgressNew(bm); get_effect_matrix_info(_emr, &no_columns, &no_rows, &x_offset, &y_offset); if ((src_rr = new_row_fetcher(bm, x1 - x_offset, x2 + (no_columns - x_offset - 1), tile_flags, TILE_BM_READ_ONLY, 0)) != 0) { Int32 j; for (j = 0; j < no_rows - 1; j++) { src_rows[j] = rf_get_bitmap_row(src_rr, y1 - y_offset + j); if (src_rows[j] == 0L) // unable to access this line? { delete_row_fetcher(src_rr, true); // free all buffered lines return FILTER_MEM_ERR; } } bounds = bm->mask_rect; dt = nullptr; for (y = y1; y < y2; y++) { if (((y - y1) % bm->preferred_tile_height) == 0) { BfProgressUpdate(bm, pid, progress_cnt++, progress_max, *apply_filter_str); if (dt) { BfBitmapTileDetach(bm, dt, true); // apply the destination tile BfUpdateView(bm); } bounds.y1 = y; bounds.y2 = LMin(y2, y + bm->preferred_tile_height); dt = BfBitmapTileGet(bm, &bounds, 0, 0, TILE_BM_WRITE, 0); if (dt == nullptr) { err = FILTER_MEM_ERR; break; } dst = (UChar*) dt->addr; if (thread && thread->TestBreak()) // force exit? { err = FILTER_ABORT; break; } } j = no_rows - 1; src_rows[j] = rf_get_bitmap_row(src_rr, y + (j - y_offset)); // ask for the next line if (src_rows[j] == 0L) // unable to access this line? { err = FILTER_MEM_ERR; break; } apply_matrix_effect(_emr, (void**) src_rows, dst, width); // apply the matrix function to the current destination line rf_free_bitmap_row(src_rr, y - y_offset); // we don't need this line for the next loop for (j = 1; j < no_rows; j++) // swap the source line pointers src_rows[j - 1] = src_rows[j]; dst += dt->width; // next destination line } if (dt) { BfBitmapTileDetach(bm, dt, err == FILTER_OK); // apply the destination tile BfUpdateView(bm); } delete_row_fetcher(src_rr, true); // free all buffered lines BfProgressDelete(bm, pid); } return err; }