float get_usage (const Image& image) { size_t non_zero_pixels = 0, total_pixels = image.Width () * image.Height (); const Color* pixel = reinterpret_cast<const Color*> (image.Bitmap ()); for (size_t i=total_pixels; i--; pixel++) if (pixel->red || pixel->green || pixel->blue) non_zero_pixels++; return float (non_zero_pixels) / total_pixels; }
void Node::FillImages (Image& image) { if (child [0]) child [0]->FillImages (image); if (image_id) { Color* dst = reinterpret_cast<Color*> (image.Bitmap ()) + rect.top * image.Width () + rect.left; Color src = color; size_t step = image.Width () - rect.width; for (size_t height=rect.height; height--; dst += step) { for (size_t width=rect.width; width--; dst++) *dst = src; } } if (child [1]) child [1]->FillImages (image); }
int main () { try { srand (0); //генерация картинок typedef stl::vector<ImageDesc> ImageArray; ImageArray images; images.reserve (IMAGES_COUNT); for (unsigned int i=0; i<IMAGES_COUNT; i++) { // ImageDesc image (i, rand () % MAX_IMAGE_WIDTH + 1, rand () % MAX_IMAGE_HEIGHT + 1); ImageDesc image (i, (unsigned int) (1 + (sinf (float (i)) + 1.0) * MAX_IMAGE_WIDTH), (unsigned int) (1 + (cosf (float (i)) + 1.0f) * MAX_IMAGE_HEIGHT)); // ImageDesc image (i, i + 1, i + 1); unsigned char* colors = &image.color.red; colors [i%3] = (unsigned char)(rand () % 128 + 127); images.push_back (image); } //сортировка картинок stl::sort (images.begin (), images.end (), &image_order); //заполнение дерева картинками size_t bad_inserts; Node* root = 0; unsigned int large_image_width = START_LARGE_IMAGE_WIDTH, large_image_height = START_LARGE_IMAGE_HEIGHT; clock_t start_time = clock (); int next_edge = 0; size_t iterations_count = 0; for (;;) { iterations_count++; //инициализация корневого узла root = new Node; root->rect = Rect (0, 0, large_image_width, large_image_height); bad_inserts = 0; for (size_t i=0; i<images.size (); i++) { if (!root->Insert (images [i])) { bad_inserts++; break; // printf ("failed image insert %d width=%u height=%u\n", images [i].id, images [i].width, images [i].height); } } // printf ("Bad inserts: %u (%.2f%%)\n", bad_inserts, 100 * float (bad_inserts) / images.size ()); if (!bad_inserts) break; delete root; if (next_edge) large_image_width *= 2; else large_image_height *= 2; next_edge = !next_edge; } //вывод результатов // root->PrintImages (); //сохранение картинки printf ("Create large image (%ux%u)...\n", large_image_width, large_image_height); Image result (large_image_width, large_image_height, 1, PixelFormat_RGB8); memset (result.Bitmap (), 0, large_image_width * large_image_height * sizeof (Color)); root->FillImages (result); clock_t end_time = clock (); result.Save (RESULT_IMAGE_NAME); //вывод статистики printf ("At time: %.2f seconds\n", float (end_time - start_time) / CLOCKS_PER_SEC); printf ("Iterations count: %u\n", iterations_count); printf ("Image size: %ux%u\n", large_image_width, large_image_height); printf ("Usage: %.2f%%\n", get_usage (result) * 100); return 0; } catch (std::exception& exception) { printf ("exception: %s\n", exception.what ()); } }