int main(int argc, char **argv) { // Determine what the output image should be char filename[14]; if (argc > 1) { if (strcmp(argv[1], "reference") == 0) { strcpy(filename, "reference.png"); } else if (strcmp(argv[1], "custom") == 0) { strcpy(filename, "custom.png"); } else if (strcmp(argv[1], "fancy") == 0) { strcpy(filename, "fancy.png"); } else { fprintf(stderr, "Incorrect argument recieved\nUsage: %s reference.png | custom.png\n", argv[0]); return 1; } } else { // No argument fprintf(stderr, "No argument recieved\nUsage: %s reference.png | custom.png\n", argv[0]); return 2; } // Prepare the reference scene if (strcmp(filename, "reference.png") == 0) { setUpReference(); } else if (strcmp(filename, "custom.png") == 0) { setUpCustom(); } else if (strcmp(filename, "fancy.png") == 0) { printf("fancy should run in around 5-10 minutes.\n"); setUpFancy(); } // Camera position cameraPos = point_new(0, 0, 0); // Prepare PNG data array char imageData[width*height*3]; int imagePos = 0; intersect_t intersect; color_t color; // Calculate the color of each pixel for (float j = 0; j < height; j++) { for (float i = 0; i < width; i++) { if (strcmp(filename, "reference.png") == 0) { color = getPixel(i, j, &intersect); } else if (strcmp(filename, "custom.png") == 0) { color = getAntialiasedPixel(i, j, &intersect, 2); } else { color = getAntialiasedPixel(i, j, &intersect, 5); // Really ramp it up } imageData[imagePos++] = color.r; imageData[imagePos++] = color.g; imageData[imagePos++] = color.b; } } // Write image out to PNG stbi_write_png(filename, width, height, 3, imageData, width*3); return 0; }
int write_image(const char *filename, ImageData &data) { return stbi_write_png(filename, data.w, data.h, data.bpp, data.data, 0); }
bool Image::save(core::FileSystem::Ptr fs, const std::string &filename) { if (type != TextureType::Texture2D) return false; unsigned int components = 0; if (format == TextureFormat::R8) components = 1; else if (format == TextureFormat::RG8) components = 2; else if (format == TextureFormat::RGBA8) components = 4; if (components == 0) return false; std::string extension = tolower(filename.substr(filename.rfind("."))); if (extension == ".png") { core::File::Ptr file = fs->open(filename, core::FileAccess::Write, true); if (!file) return false; unsigned int stride = TextureFormat::getSize(format, width, 1, 1); if (!stbi_write_png(file, width, height, components, imagedata, stride)) return false; } else if (extension == ".tga") { core::File::Ptr file = fs->open(filename, core::FileAccess::Write, true); if (!file) return false; if (!stbi_write_tga(file, width, height, components, imagedata)) return false; } else if (extension == ".bmp") { core::File::Ptr file = fs->open(filename, core::FileAccess::Write, true); if (!file) return false; if (!stbi_write_bmp(file, width, height, components, imagedata)) return false; } else { return false; } return true; }
int main(int argc, char **argv) { /* Command-line argument default values */ char *filenameIn = NULL; char *filenameOut = NULL; double radius = 1; int x = 0, y = 0, size = 80, kernelSize = 5; if (!parseArgs(argc, argv, &filenameIn, &filenameOut, &x, &y, &size, &kernelSize, &radius)) { return 1; } if (size < kernelSize) { printf("Size too small.\n"); return 1; } /* Load an image into memory, and set aside memory for result */ int width, height, comp; uint8_t *pixelsIn = stbi_load(filenameIn, &width, &height, &comp, 0); uint8_t *pixelsOut = (uint8_t *) malloc( height * width * comp * sizeof(uint8_t *)); if (pixelsIn == NULL) { printf("Could not load \"%s\".\n", filenameIn); free(pixelsOut); return 1; } if (pixelsOut == NULL) { printf("Could not allocate enough memory.\n"); free(pixelsIn); return 1; } memcpy(pixelsOut, pixelsIn, height * width * comp * sizeof(uint8_t)); /* Clamp x and y to available space */ x = x > width ? width : x; y = y > height ? height : y; double *kernel = (double *) malloc(kernelSize * kernelSize * sizeof(double)); double sum = computeKernel(kernel, kernelSize, radius // sigma ); normalise(kernel, sum, kernelSize, kernelSize); convolve(width, height, x, // Define box y, // x + size, // y + size, // comp, // components pixelsIn, // in pixelsOut, // out kernel, // kernel kernelSize // kernelSize ); if (stbi_write_png(filenameOut, width, height, comp, pixelsOut, 0) == 0) { printf("Could not write \"%s\"\n", filenameOut); } else { printf("Wrote: %s (%ix%ix%i) " \ "(x=%i, y=%i, size=%i) " \ "to %s\n", filenameIn, height, width, x, y, size, comp, filenameOut); } free(pixelsIn); free(pixelsOut); free(filenameIn); free(filenameOut); return 0; }
/** * Cellular automata sample main function. * */ int main(int argc, char* argv[]) { /* Wrappers for OpenCL objects. */ CCLContext* ctx; CCLDevice* dev; CCLImage* img1; CCLImage* img2; CCLProgram* prg; CCLKernel* krnl; CCLEvent* evt1; CCLEvent* evt2; /* Other variables. */ CCLEventWaitList ewl = NULL; /* Profiler object. */ CCLProf* prof; /* Output images filename. */ char* filename; /* Selected device, may be given in command line. */ int dev_idx = -1; /* Error handling object (must be NULL). */ GError* err = NULL; /* Does selected device support images? */ cl_bool image_ok; /* Initial sim state. */ cl_uchar4* input_image; /* Simulation states. */ cl_uchar4** output_images; /* RNG seed, may be given in command line. */ unsigned int seed; /* Image file write status. */ int file_write_status; /* Image format. */ cl_image_format image_format = { CL_RGBA, CL_UNSIGNED_INT8 }; /* Thread data. */ struct thread_data td; /* Global and local worksizes. */ size_t gws[2]; size_t lws[2]; /* Threads. */ GThread* comm_thread; GThread* exec_thread; /* Check arguments. */ if (argc >= 2) { /* Check if a device was specified in the command line. */ dev_idx = atoi(argv[1]); } if (argc >= 3) { /* Check if a RNG seed was specified. */ seed = atoi(argv[2]); } else { seed = (unsigned int) time(NULL); } /* Initialize RNG. */ srand(seed); /* Create random initial state. */ input_image = (cl_uchar4*) malloc(CA_WIDTH * CA_HEIGHT * sizeof(cl_uchar4)); for (cl_uint i = 0; i < CA_WIDTH * CA_HEIGHT; ++i) { cl_uchar state = (rand() & 0x3) ? 0xFF : 0x00; input_image[i] = (cl_uchar4) {{ state, state, state, 0xFF }}; } /* Allocate space for simulation results. */ output_images = (cl_uchar4**) malloc((CA_ITERS + 1) * sizeof(cl_uchar4*)); for (cl_uint i = 0; i < CA_ITERS + 1; ++i) output_images[i] = (cl_uchar4*) malloc(CA_WIDTH * CA_HEIGHT * sizeof(cl_uchar4)); /* Create context using device selected from menu. */ ctx = ccl_context_new_from_menu_full(&dev_idx, &err); HANDLE_ERROR(err); /* Get first device in context. */ dev = ccl_context_get_device(ctx, 0, &err); HANDLE_ERROR(err); /* Ask device if it supports images. */ image_ok = ccl_device_get_info_scalar( dev, CL_DEVICE_IMAGE_SUPPORT, cl_bool, &err); HANDLE_ERROR(err); if (!image_ok) ERROR_MSG_AND_EXIT("Selected device doesn't support images."); /* Create command queues. */ queue_exec = ccl_queue_new(ctx, dev, CL_QUEUE_PROFILING_ENABLE, &err); HANDLE_ERROR(err); queue_comm = ccl_queue_new(ctx, dev, CL_QUEUE_PROFILING_ENABLE, &err); HANDLE_ERROR(err); /* Create 2D image for initial state. */ img1 = ccl_image_new(ctx, CL_MEM_READ_WRITE, &image_format, NULL, &err, "image_type", (cl_mem_object_type) CL_MEM_OBJECT_IMAGE2D, "image_width", (size_t) CA_WIDTH, "image_height", (size_t) CA_HEIGHT, NULL); HANDLE_ERROR(err); /* Create another 2D image for double buffering. */ img2 = ccl_image_new(ctx, CL_MEM_READ_WRITE, &image_format, NULL, &err, "image_type", (cl_mem_object_type) CL_MEM_OBJECT_IMAGE2D, "image_width", (size_t) CA_WIDTH, "image_height", (size_t) CA_HEIGHT, NULL); HANDLE_ERROR(err); /* Create program from kernel source and compile it. */ prg = ccl_program_new_from_source(ctx, CA_KERNEL, &err); HANDLE_ERROR(err); ccl_program_build(prg, NULL, &err); HANDLE_ERROR(err); /* Get kernel wrapper. */ krnl = ccl_program_get_kernel(prg, "ca", &err); HANDLE_ERROR(err); /* Determine nice local and global worksizes. */ ccl_kernel_suggest_worksizes(krnl, dev, 2, real_ws, gws, lws, &err); HANDLE_ERROR(err); printf("\n * Global work-size: (%d, %d)\n", (int) gws[0], (int) gws[1]); printf(" * Local work-size: (%d, %d)\n", (int) lws[0], (int) lws[1]); /* Create thread communication queues. */ comm_thread_queue = g_async_queue_new(); exec_thread_queue = g_async_queue_new(); host_thread_queue = g_async_queue_new(); /* Setup thread data. */ td.krnl = krnl; td.img1 = img1; td.img2 = img2; td.gws = gws; td.lws = lws; td.output_images = output_images; /* Create threads. */ exec_thread = g_thread_new("exec_thread", exec_func, &td); comm_thread = g_thread_new("comm_thread", comm_func, &td); /* Start profiling. */ prof = ccl_prof_new(); ccl_prof_start(prof); /* Write initial state. */ ccl_image_enqueue_write(img1, queue_comm, CL_TRUE, origin, region, 0, 0, input_image, NULL, &err); HANDLE_ERROR(err); /* Run CA_ITERS iterations of the CA. */ for (cl_uint i = 0; i < CA_ITERS; ++i) { /* Send message to comms thread. */ g_async_queue_push(comm_thread_queue, &go_msg); /* Send message to exec thread. */ g_async_queue_push(exec_thread_queue, &go_msg); /* Get event wrappers from both threads. */ evt1 = (CCLEvent*) g_async_queue_pop(host_thread_queue); evt2 = (CCLEvent*) g_async_queue_pop(host_thread_queue); /* Can't continue until this iteration is over. */ ccl_event_wait_list_add(&ewl, evt1, evt2, NULL); /* Wait for events. */ ccl_event_wait(&ewl, &err); HANDLE_ERROR(err); } /* Send message to comms thread to read last result. */ g_async_queue_push(comm_thread_queue, &go_msg); /* Send stop messages to both threads. */ g_async_queue_push(comm_thread_queue, &stop_msg); g_async_queue_push(exec_thread_queue, &stop_msg); /* Get event wrapper from comms thread. */ evt1 = (CCLEvent*) g_async_queue_pop(host_thread_queue); /* Can't continue until final read is over. */ ccl_event_wait_list_add(&ewl, evt1, NULL); ccl_event_wait(&ewl, &err); HANDLE_ERROR(err); /* Make sure both queues are finished. */ ccl_queue_finish(queue_comm, &err); HANDLE_ERROR(err); ccl_queue_finish(queue_exec, &err); HANDLE_ERROR(err); /* Stop profiling timer and add queues for analysis. */ ccl_prof_stop(prof); ccl_prof_add_queue(prof, "Comms", queue_comm); ccl_prof_add_queue(prof, "Exec", queue_exec); /* Allocate space for base filename. */ filename = (char*) malloc( (strlen(IMAGE_FILE_PREFIX ".png") + IMAGE_FILE_NUM_DIGITS + 1) * sizeof(char)); /* Write results to image files. */ for (cl_uint i = 0; i < CA_ITERS; ++i) { /* Determine next filename. */ sprintf(filename, "%s%0" G_STRINGIFY(IMAGE_FILE_NUM_DIGITS) "d.png", IMAGE_FILE_PREFIX, i); /* Save next image. */ file_write_status = stbi_write_png(filename, CA_WIDTH, CA_HEIGHT, 4, output_images[i], CA_WIDTH * sizeof(cl_uchar4)); /* Give feedback if unable to save image. */ if (!file_write_status) { ERROR_MSG_AND_EXIT("Unable to save image in file."); } } /* Process profiling info. */ ccl_prof_calc(prof, &err); HANDLE_ERROR(err); /* Print profiling info. */ ccl_prof_print_summary(prof); /* Save profiling info. */ ccl_prof_export_info_file(prof, "prof.tsv", &err); HANDLE_ERROR(err); /* Destroy threads. */ g_thread_join(exec_thread); g_thread_join(comm_thread); /* Destroy thread communication queues. */ g_async_queue_unref(comm_thread_queue); g_async_queue_unref(exec_thread_queue); g_async_queue_unref(host_thread_queue); /* Release host buffers. */ free(filename); free(input_image); for (cl_uint i = 0; i < CA_ITERS + 1; ++i) free(output_images[i]); free(output_images); /* Release wrappers. */ ccl_image_destroy(img1); ccl_image_destroy(img2); ccl_program_destroy(prg); ccl_queue_destroy(queue_comm); ccl_queue_destroy(queue_exec); ccl_context_destroy(ctx); /* Destroy profiler. */ ccl_prof_destroy(prof); /* Check all wrappers have been destroyed. */ g_assert(ccl_wrapper_memcheck()); /* Terminate. */ return 0; }
int main(int argc, char **argv) { stbtt_fontinfo font; unsigned char *bitmap; int w,h,i,j,c = (argc > 1 ? atoi(argv[1]) : 34807), s = (argc > 2 ? atoi(argv[2]) : 32); //debug(); // @TODO: why is minglui.ttc failing? fread(ttf_buffer, 1, 1<<25, fopen(argc > 3 ? argv[3] : "c:/windows/fonts/mingliu.ttc", "rb")); //fread(ttf_buffer, 1, 1<<25, fopen(argc > 3 ? argv[3] : "c:/x/DroidSansMono.ttf", "rb")); { static stbtt_pack_context pc; static stbtt_packedchar cd[256]; static unsigned char atlas[1024*1024]; stbtt_PackBegin(&pc, atlas, 1024,1024,1024,1,NULL); stbtt_PackFontRange(&pc, ttf_buffer, 0, 32.0, 0, 256, cd); stbtt_PackEnd(&pc); } #if 0 stbtt_BakeFontBitmap(ttf_buffer,stbtt_GetFontOffsetForIndex(ttf_buffer,0), 40.0, temp_bitmap[0],BITMAP_W,BITMAP_H, 32,96, cdata); // no guarantee this fits! stbi_write_png("fonttest1.png", BITMAP_W, BITMAP_H, 1, temp_bitmap, 0); { stbtt_pack_context pc; stbtt_PackBegin(&pc, temp_bitmap[0], BITMAP_W, BITMAP_H, 0, 1, NULL); stbtt_PackFontRange(&pc, ttf_buffer, 0, 20.0, 32, 95, pdata); stbtt_PackFontRange(&pc, ttf_buffer, 0, 20.0, 0xa0, 0x100-0xa0, pdata); stbtt_PackEnd(&pc); stbi_write_png("fonttest2.png", BITMAP_W, BITMAP_H, 1, temp_bitmap, 0); } { stbtt_pack_context pc; stbtt_pack_range pr[2]; stbtt_PackBegin(&pc, temp_bitmap[0], BITMAP_W, BITMAP_H, 0, 1, NULL); pr[0].chardata_for_range = pdata; pr[0].first_unicode_char_in_range = 32; pr[0].num_chars_in_range = 95; pr[0].font_size = 20.0f; pr[1].chardata_for_range = pdata+256; pr[1].first_unicode_char_in_range = 0xa0; pr[1].num_chars_in_range = 0x100 - 0xa0; pr[1].font_size = 20.0f; stbtt_PackSetOversampling(&pc, 2, 2); stbtt_PackFontRanges(&pc, ttf_buffer, 0, pr, 2); stbtt_PackEnd(&pc); stbi_write_png("fonttest3.png", BITMAP_W, BITMAP_H, 1, temp_bitmap, 0); } return 0; #endif stbtt_InitFont(&font, ttf_buffer, stbtt_GetFontOffsetForIndex(ttf_buffer,0)); bitmap = stbtt_GetCodepointBitmap(&font, 0,stbtt_ScaleForPixelHeight(&font, (float)s), c, &w, &h, 0,0); for (j=0; j < h; ++j) { for (i=0; i < w; ++i) putchar(" .:ioVM@"[bitmap[j*w+i]>>5]); putchar('\n'); } return 0; }
int main( int argc, char* argv[]) { if(argc < 6) { std::cout<< "All File arguments are required!!" << std::endl; exit(-1); } uint32_t total_frames = std::stoi(argv[1], nullptr, 10); uint32_t key_frame_interval = std::stoi(argv[2], nullptr, 10); std::string dir_path(argv[3]); uint32_t search_area = std::stoi(argv[4], nullptr, 10); int32_t vErrThreshold = std::stoi(argv[5], nullptr, 10); std::string out_file_path(argv[6], nullptr, 10); #if 0 std::string dir_path(argv[1]); uint32_t first_frame_idx = std::stoi(argv[2], nullptr, 10); uint32_t frame_count = std::stoi(argv[3], nullptr, 10); uint32_t search_area = std::stoi(argv[4], nullptr, 10); uint32_t pad_zero = std::stoi(argv[5], nullptr, 10); int32_t vErrThreshold = std::stoi(argv[6], nullptr, 10); std::vector<std::string> file_paths; std::vector< std::unique_ptr<MPTC::DXTImage> > dxt_frames; std::stringstream ss; std::fstream outfile; outfile.open("out.txt", std::ios::out); //MPTC::DXTImage dxt_img(img_path, true, 0); ss.str(""); ss << std::setw(pad_zero) << std::setfill('0') << first_frame_idx; std::string frame_num_str = ss.str(); std::string file_path = dir_path + "/" + frame_num_str+ ".png"; file_paths.push_back(file_path); MPTC::DXTImage::SetPattern(static_cast<int32_t>(search_area)); std::unique_ptr<MPTC::DXTImage> dxt_img(new MPTC::DXTImage(file_path, true, 0, vErrThreshold)); std::unique_ptr<MPTC::DXTImage> null_dxt(nullptr); dxt_frames.push_back(std::move(dxt_img)); std::cout << "Frame Number:" << 0 << std::endl; std::cout << "Before PSNR: " << dxt_frames[0]->PSNR() << std::endl; dxt_frames[0]->Reencode(null_dxt, 0); std::cout << "After PSNR: " << dxt_frames[0]->PSNR() << std::endl; std::cout << "Intra block motion size:" << dxt_frames[0]->_motion_indices.size() << std::endl; std::vector<uint8_t> palette = std::move(dxt_frames[0]->Get8BitPalette()); std::vector<uint64_t> count_palette(256, 0); std::vector<uint64_t> count_intra(256, 0); std::vector<uint64_t> total_counts(256,0); for(auto a : dxt_frames[0]->_intra_motion_indices) { count_intra[std::get<0>(a)]++; count_intra[std::get<1>(a)]++; total_counts[std::get<0>(a)]++; total_counts[std::get<1>(a)]++; } uint64_t Total = std::accumulate(count_intra.begin(), count_intra.end(), 0U); double entropy = 0.0; for( auto e : count_intra ) { if(e!=0) { double p = static_cast<double>(e)/static_cast<double>(Total); entropy += (-1.0 * p * log2(p)); } } std::cout << "Total:" << Total << std::endl; std::cout << "Entropy:" << entropy << std::endl; //Entropy encode motion indices //*****************MAX BYTES ******************* uint32_t max_bytes = 180000; std::vector<uint8_t> compressed_data(max_bytes, 0); entropy::Arithmetic_Codec ace(max_bytes, compressed_data.data()); entropy::Adaptive_Data_Model model(257); ace.start_encoder(); for(auto a : dxt_frames[0]->_motion_indices) { ace.encode(std::get<0>(a), model); ace.encode(std::get<1>(a), model); } ace.stop_encoder(); std::cout << "Compressed motion index bytes:" << ace.get_num_bytes() << std::endl; // Entropy encode index mask std::vector<uint8_t> compressed_mask(max_bytes, 0); entropy::Arithmetic_Codec ace_mask(max_bytes, compressed_mask.data()); entropy::Adaptive_Bit_Model mask_bit_model; ace_mask.start_encoder(); for(auto a : dxt_frames[0]->_index_mask) { ace_mask.encode(a, mask_bit_model); } ace_mask.stop_encoder(); std::cout << "Compressed Mask bytes:" << ace_mask.get_num_bytes() << std::endl; #if 0 //Entropy Decode entropy::Arithmetic_Codec ade(max_bytes, compressed_data.data()); entropy::Adaptive_Data_Model decode_model(257); ade.start_decoder(); std::vector<std::tuple<uint8_t, uint8_t> > decoded_symbols; for(int i = 0; i < dxt_frames[0]->_motion_indices.size(); i++) { uint8_t sym1 = ade.decode(decode_model); uint8_t sym2 = ade.decode(decode_model); decoded_symbols.push_back(std::make_tuple(sym1, sym2)); #ifdef NDEBUG auto a = dxt_frames[0]->_motion_indices[i]; std::cout << sym1 << "-" << std::get<0>(a) << std::endl; std::cout << sym2 << "-" << std::get<1>(a) << std::endl; #endif assert(dxt_frames[0]->_motion_indices[i] == decoded_symbols[i]); } ade.stop_decoder(); //Entropy decode mask bits entropy::Arithmetic_Codec ade_mask(max_bytes,compressed_mask.data()); entropy::Adaptive_Bit_Model decode_mask_bit_model; ade_mask.start_decoder(); std::vector<uint8_t> decoded_mask; for(int i = 0; i < dxt_frames[0]->_motion_indices.size(); i++) { uint8_t sym = ade_mask.decode(decode_mask_bit_model); decoded_mask.push_back(sym); #ifndef NDEBUG auto a = dxt_frames[0]->_index_mask[i]; std::cout << static_cast<int>(sym) << " -- " << static_cast<int>(a) << std::endl; #endif assert(sym == dxt_frames[0]->_index_mask[i]); } ade_mask.stop_decoder(); #endif uint32_t total_bits = ace.get_num_bytes() * 8 + dxt_frames[0]->_unique_palette.size() * 32 + ace_mask.get_num_bytes() * 8; float total_bytes = static_cast<float>(total_bits)/8; outfile << total_bytes+10 << "\t" << dxt_frames[0]->PSNR() << std::endl; std::cout << "*****Total bytes****:" << total_bytes << std::endl; float bpp = static_cast<float>(total_bits)/(dxt_frames[0]->_width * dxt_frames[0]->_height); std::cout << "BPP:" << bpp << "\t" << dxt_frames[0]->PSNR() << std::endl; std::unique_ptr<MPTC::RGBAImage> ep1 = std::move(dxt_frames[0]->EndpointOneImage()); std::vector<uint8_t> ep1_vector = std::move(ep1->Pack()); stbi_write_png("ep1.png", ep1->Width(), ep1->Height(), 4, ep1->Pack().data(), 4 * ep1->Width()); std::unique_ptr<MPTC::RGBAImage> ep2 = std::move(dxt_frames[0]->EndpointTwoImage()); std::vector<uint8_t> ep2_vector = std::move(ep2->Pack()); stbi_write_png("ep2.png", ep2->Width(), ep2->Height(), 4, ep2->Pack().data(), 4 * ep2->Width()); std::vector<uint32_t> ep_diff; int max_diff = std::numeric_limits<int>::min(); int min_diff = std::numeric_limits<int>::max(); std::vector<uint32_t> count_ep(512, 0); for(size_t ep_idx = 0; ep_idx < ep1_vector.size(); ep_idx++) { if(ep_idx % 4 == 3) continue; int diff = static_cast<int>(ep1_vector[ep_idx]) - static_cast<int>(ep2_vector[ep_idx]); if(diff > max_diff) max_diff = diff; if(diff < min_diff) min_diff = diff; ep_diff.push_back(static_cast<uint32_t>(diff + 255)); count_ep[ep_diff[ep_diff.size() - 1]]++; } uint64_t Total_ep = std::accumulate(count_ep.begin(), count_ep.end(), 0U); double entropy_ep = 0.0; for( auto e : count_ep ) { if(e!=0) { double p = static_cast<double>(e)/static_cast<double>(Total_ep); entropy_ep += (-1.0 * p * log2(p)); } } // Entropy encode endpoint std::vector<uint8_t> compressed_ep(max_bytes, 0); entropy::Arithmetic_Codec ace_ep(max_bytes, compressed_ep.data()); entropy::Adaptive_Data_Model ep_model; ace_ep.start_encoder(); for(auto a :ep_diff) { ace_ep.encode(a, mask_bit_model); } ace_ep.stop_encoder(); std::cout << "----EndPoint compressed----:" << ace_ep.get_num_bytes() << std::endl; std::cout << "Total end point:" << Total_ep << std::endl; std::cout << "Entropy end point:" << entropy_ep << std::endl; ReconstructImage(dxt_frames, 0); std::cout << "PSNR after decompression: " << dxt_frames[0]->PSNR() << std::endl; for(uint32_t i = first_frame_idx + 1; i <= first_frame_idx + frame_count; i++) { ss.str(""); ss << std::setw(pad_zero) << std::setfill('0') << i; std::string frame_num_str = ss.str(); std::string file_path = dir_path + "/" + frame_num_str+ ".png"; std::unique_ptr<MPTC::DXTImage> dxt_img1(new MPTC::DXTImage(file_path, false, search_area, vErrThreshold)); dxt_frames.push_back(std::move(dxt_img1)); file_paths.push_back(file_path); } double combined_bpp = bpp; for(size_t i = 1; i < dxt_frames.size(); i++) { //*****************MAX BYTES ******************* std::cout << std::endl << std::endl; std::cout << "Frame Number:" << i << std::endl; std::cout << "Before PSNR:" << dxt_frames[i]->PSNR() << std::endl; dxt_frames[i]->Reencode(dxt_frames[i-1], -1); std::cout << "After PSNR:" << dxt_frames[i]->PSNR() << std::endl; std::cout << "Total unique indices:" << dxt_frames[i]->_unique_palette.size()<< std::endl; std::cout << "Intra block motion size:" << dxt_frames[i]->_intra_motion_indices.size()<<std::endl; std::cout << "Inter block motion size:" << dxt_frames[i]->_inter_block_motion_indices.size() << std::endl; std::cout << "Inter pixel motion size:" << dxt_frames[i]->_inter_pixel_motion_indices.size() << std::endl; uint32_t max_bytes_inter = 180000; std::vector<uint8_t> compressed_data_inter(max_bytes_inter, 0); entropy::Arithmetic_Codec ace_inter(max_bytes_inter, compressed_data_inter.data()); entropy::Adaptive_Data_Model model_inter(257); ace_inter.start_encoder(); for(auto a : dxt_frames[i]->_motion_indices) { ace_inter.encode(std::get<0>(a), model_inter); ace_inter.encode(std::get<1>(a), model_inter); } ace_inter.stop_encoder(); // Entropy encode index mask std::vector<uint8_t> compressed_mask_inter(max_bytes_inter, 0); entropy::Arithmetic_Codec ace_mask_inter(max_bytes_inter, compressed_mask_inter.data()); entropy::Adaptive_Bit_Model mask_bit_model_inter; ace_mask_inter.start_encoder(); for(auto a : dxt_frames[i]->_index_mask) { ace_mask_inter.encode(a, mask_bit_model_inter); } ace_mask_inter.stop_encoder(); //Entropy Decode entropy::Arithmetic_Codec ade(max_bytes, compressed_data_inter.data()); entropy::Adaptive_Data_Model decode_model(257); ade.start_decoder(); std::vector<std::tuple<uint8_t, uint8_t> > decoded_symbols; for(int ii = 0; ii < dxt_frames[i]->_motion_indices.size(); ii++) { uint8_t sym1 = ade.decode(decode_model); uint8_t sym2 = ade.decode(decode_model); decoded_symbols.push_back(std::make_tuple(sym1, sym2)); #if 0 auto a = dxt_frames[]->_motion_indices[i]; std::cout << sym1 << "-" << std::get<0>(a) << std::endl; std::cout << sym2 << "-" << std::get<1>(a) << std::endl; #endif assert(dxt_frames[i]->_motion_indices[ii] == decoded_symbols[ii]); } ade.stop_decoder(); //Entropy decode mask bits entropy::Arithmetic_Codec ade_mask(max_bytes,compressed_mask_inter.data()); entropy::Adaptive_Bit_Model decode_mask_bit_model; ade_mask.start_decoder(); std::vector<uint8_t> decoded_mask; for(int ii = 0; ii < dxt_frames[i]->_index_mask.size(); ii++) { uint8_t sym = ade_mask.decode(decode_mask_bit_model); decoded_mask.push_back(sym); #if 0 auto a = dxt_frames[0]->_index_mask[i]; std::cout << static_cast<int>(sym) << " -- " << static_cast<int>(a) << std::endl; #endif assert(sym == dxt_frames[i]->_index_mask[ii]); } ade_mask.stop_decoder(); std::vector<uint64_t> counts(256,0); uint8_t max = std::numeric_limits<uint8_t>::min(); uint8_t min = std::numeric_limits<uint8_t>::max(); for(auto a : dxt_frames[i]->_motion_indices) { counts[std::get<0>(a)]++; counts[std::get<1>(a)]++; total_counts[std::get<0>(a)]++; total_counts[std::get<1>(a)]++; max = std::max(std::max(max, std::get<0>(a)), std::get<1>(a)); min = std::min(std::min(min, std::get<0>(a)), std::get<1>(a)); } Total = std::accumulate(counts.begin(), counts.end(), 0U); entropy = 0.0; for( auto e : counts ) { if(e!=0) { double p = static_cast<double>(e)/static_cast<double>(Total); entropy += (-1.0 * p * log2(p)); } } std::cout << "Total:" << Total << std::endl; std::cout << "Entropy:" << entropy << std::endl; total_bits = ace_inter.get_num_bytes() * 8 + 1000 + dxt_frames[0]->_unique_palette.size() * 32 + ace_mask_inter.get_num_bytes() * 8; total_bytes = static_cast<float>(total_bits)/8; std::cout << "Compressed motion index bytes:" << ace_inter.get_num_bytes() << std::endl; std::cout << "Compressed Mask bytes:" << ace_mask_inter.get_num_bytes() << std::endl; std::cout << "Total bytes:" << total_bytes << std::endl; bpp = static_cast<float>(total_bits)/(dxt_frames[0]->_width * dxt_frames[0]->_height); std::cout << "BPP:" << bpp << std::endl; combined_bpp += bpp; } std::cout << std::endl << std::endl; std::cout << "Combined BPP:" << combined_bpp << std::endl; #endif return 0; }
static void writeTextureToFile(int textureWidth, int textureHeight, const char* fileName, FILE* ffmpegVideo) { int numComponents = 4; //glPixelStorei(GL_PACK_ALIGNMENT,1); GLuint err=glGetError(); assert(err==GL_NO_ERROR); //glReadBuffer(GL_BACK);//COLOR_ATTACHMENT0); err=glGetError(); assert(err==GL_NO_ERROR); float* orgPixels = (float*)malloc(textureWidth*textureHeight*numComponents*4); glReadPixels(0,0,textureWidth, textureHeight, GL_RGBA, GL_FLOAT, orgPixels); //it is useful to have the actual float values for debugging purposes //convert float->char char* pixels = (char*)malloc(textureWidth*textureHeight*numComponents); err=glGetError(); assert(err==GL_NO_ERROR); for (int j=0;j<textureHeight;j++) { for (int i=0;i<textureWidth;i++) { pixels[(j*textureWidth+i)*numComponents] = orgPixels[(j*textureWidth+i)*numComponents]*255.f; pixels[(j*textureWidth+i)*numComponents+1]=orgPixels[(j*textureWidth+i)*numComponents+1]*255.f; pixels[(j*textureWidth+i)*numComponents+2]=orgPixels[(j*textureWidth+i)*numComponents+2]*255.f; pixels[(j*textureWidth+i)*numComponents+3]=orgPixels[(j*textureWidth+i)*numComponents+3]*255.f; } } if (ffmpegVideo) { fwrite(pixels, textureWidth*textureHeight*numComponents, 1, ffmpegVideo); //fwrite(pixels, 100,1,ffmpegVideo);//textureWidth*textureHeight*numComponents, 1, ffmpegVideo); } else { if (1) { //swap the pixels unsigned char tmp; for (int j=0;j<textureHeight/2;j++) { for (int i=0;i<textureWidth;i++) { for (int c=0;c<numComponents;c++) { tmp = pixels[(j*textureWidth+i)*numComponents+c]; pixels[(j*textureWidth+i)*numComponents+c]= pixels[((textureHeight-j-1)*textureWidth+i)*numComponents+c]; pixels[((textureHeight-j-1)*textureWidth+i)*numComponents+c] = tmp; } } } } stbi_write_png(fileName, textureWidth,textureHeight, numComponents, pixels, textureWidth*numComponents); } free(pixels); free(orgPixels); }
void Image::SaveFile(const char *filename ) { stbi_write_png(filename, this->width, this->height, 4, this->pixels, this->width * this->bpp); }
int main(int argc, const char** argv) { // Number of sites to generate int count = 200; if( argc > 1 ) count = atol(argv[1]); // Image dimension int dimension = 512; if( argc > 2 ) dimension = atol(argv[2]); voronoi::Point* points = new voronoi::Point[count]; if( !points ) return 1; int pointoffset = 10; // move the points inwards, for aestetic reasons srand(0); for( int i = 0; i < count; ++i ) { points[i].x = float(pointoffset + rand() % (dimension-2*pointoffset)); points[i].y = float(pointoffset + rand() % (dimension-2*pointoffset)); } voronoi::Voronoi generator; generator.generate(count, points, dimension, dimension); size_t imagesize = dimension*dimension*3; unsigned char* image = (unsigned char*)malloc(imagesize); memset(image, 0, imagesize); unsigned char color[] = {127, 127, 255}; unsigned char color_pt[] = {255, 255, 255}; const struct voronoi::Edge* edge = generator.get_edges(); while( edge ) { plot_line(edge->pos[0].x, edge->pos[0].y, edge->pos[1].x, edge->pos[1].y, image, dimension, 3, color); edge = edge->next; } // Plot the sites for( int i = 0; i < count; ++i ) { int index = points[i].y * dimension * 3 + points[i].x * 3; image[index+0] = 255; image[index+1] = 255; image[index+2] = 255; } delete[] points; char path[512]; sprintf(path, "example.png"); stbi_write_png(path, dimension, dimension, 3, image, dimension*3); printf("wrote %s\n", path); free(image); return 0; }
void SnapShot() { unsigned char *bmpBuffer; time_t tim; struct tm tm; char buf[15]; char temppath[80]; int Width = 0; int Height = 0; int i = 0; RECT rect; GetClientRect(win_get_window(), &rect); Width = rect.right - rect.left; Height = rect.bottom - rect.top; memset(&temppath[0], 0, sizeof(temppath)); //Get time/date stamp tim = time(0); tm = *localtime(&tim); strftime(buf, sizeof buf, "%Y%m%d%H%M%S", &tm); puts(buf); ////// bmpBuffer = (unsigned char*)malloc(Width*Height * 4); if (!bmpBuffer) wrlog("Error creating buffer for snapshot"); return; glReadPixels((GLint)0, (GLint)0, (GLint)Width, (GLint)Height, GL_RGBA, GL_UNSIGNED_BYTE, bmpBuffer); //Flip Texture int width_in_bytes = Width * STBI_rgb_alpha; unsigned char *top = NULL; unsigned char *bottom = NULL; unsigned char temp = 0; int half_height = Height / 2; for (int row = 0; row < half_height; row++) { top = bmpBuffer + row * width_in_bytes; bottom = bmpBuffer + (Height - row - 1) * width_in_bytes; for (int col = 0; col < width_in_bytes; col++) { temp = *top; *top = *bottom; *bottom = temp; top++; bottom++; } } strcat(temppath, "SS"); strcat(temppath, buf); strcat(temppath, ".png"); strcat(temppath, "\0"); LOG_DEBUG("Saving Snapshot: %s", temppath); stbi_write_png(temppath, Width, Height, 4, bmpBuffer, Width * 4); free(bmpBuffer); }
/** * Image filter main function. * */ int main(int argc, char * argv[]) { /* Wrappers for OpenCL objects. */ CCLContext * ctx; CCLDevice * dev; CCLImage * img_in; CCLImage * img_out; CCLQueue * queue; CCLProgram * prg; CCLKernel * krnl; CCLSampler * smplr; /* Device selected specified in the command line. */ int dev_idx = -1; /* Error handling object (must be initialized to NULL). */ CCLErr * err = NULL; /* Does selected device support images? */ cl_bool image_ok; /* Image data in host. */ unsigned char * input_image; unsigned char * output_image; /* Image properties. */ int width, height, n_channels; /* Image file write status. */ int file_write_status; /* Image parameters. */ cl_image_format image_format = { CL_RGBA, CL_UNSIGNED_INT8 }; /* Origin and region of complete image. */ size_t origin[3] = { 0, 0, 0 }; size_t region[3]; /* Real worksize. */ size_t real_ws[2]; /* Global and local worksizes. */ size_t gws[2]; size_t lws[2]; /* Check arguments. */ if (argc < 2) { ERROR_MSG_AND_EXIT("Usage: image_filter <image_file> [device_index]"); } else if (argc >= 3) { /* Check if a device was specified in the command line. */ dev_idx = atoi(argv[2]); } /* Load image. */ input_image = stbi_load(argv[1], &width, &height, &n_channels, 4); if (!input_image) ERROR_MSG_AND_EXIT(stbi_failure_reason()); /* Real work size. */ real_ws[0] = width; real_ws[1] = height; /* Set image region. */ region[0] = width; region[1] = height; region[2] = 1; /* Create context using device selected from menu. */ ctx = ccl_context_new_from_menu_full(&dev_idx, &err); HANDLE_ERROR(err); /* Get first device in context. */ dev = ccl_context_get_device(ctx, 0, &err); HANDLE_ERROR(err); /* Ask device if it supports images. */ image_ok = ccl_device_get_info_scalar( dev, CL_DEVICE_IMAGE_SUPPORT, cl_bool, &err); HANDLE_ERROR(err); if (!image_ok) ERROR_MSG_AND_EXIT("Selected device doesn't support images."); /* Create a command queue. */ queue = ccl_queue_new(ctx, dev, 0, &err); HANDLE_ERROR(err); /* Create 2D input image using loaded image data. */ img_in = ccl_image_new(ctx, CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, &image_format, input_image, &err, "image_type", (cl_mem_object_type) CL_MEM_OBJECT_IMAGE2D, "image_width", (size_t) width, "image_height", (size_t) height, NULL); HANDLE_ERROR(err); /* Create 2D output image. */ img_out = ccl_image_new(ctx, CL_MEM_WRITE_ONLY, &image_format, NULL, &err, "image_type", (cl_mem_object_type) CL_MEM_OBJECT_IMAGE2D, "image_width", (size_t) width, "image_height", (size_t) height, NULL); HANDLE_ERROR(err); /* Create program from kernel source and compile it. */ prg = ccl_program_new_from_source(ctx, FILTER_KERNEL, &err); HANDLE_ERROR(err); ccl_program_build(prg, NULL, &err); HANDLE_ERROR(err); /* Get kernel wrapper. */ krnl = ccl_program_get_kernel(prg, "do_filter", &err); HANDLE_ERROR(err); /* Determine nice local and global worksizes. */ ccl_kernel_suggest_worksizes(krnl, dev, 2, real_ws, gws, lws, &err); HANDLE_ERROR(err); /* Show information to user. */ printf("\n * Image size: %d x %d, %d channels\n", width, height, n_channels); printf(" * Global work-size: (%d, %d)\n", (int) gws[0], (int) gws[1]); printf(" * Local work-size: (%d, %d)\n", (int) lws[0], (int) lws[1]); /* Create sampler (this could also be created in-kernel). */ smplr = ccl_sampler_new(ctx, CL_FALSE, CL_ADDRESS_CLAMP_TO_EDGE, CL_FILTER_NEAREST, &err); HANDLE_ERROR(err); /* Apply filter. */ ccl_kernel_set_args_and_enqueue_ndrange( krnl, queue, 2, NULL, gws, lws, NULL, &err, img_in, img_out, smplr, NULL); HANDLE_ERROR(err); /* Allocate space for output image. */ output_image = (unsigned char *) malloc(width * height * 4 * sizeof(unsigned char)); /* Read image data back to host. */ ccl_image_enqueue_read(img_out, queue, CL_TRUE, origin, region, 0, 0, output_image, NULL, &err); HANDLE_ERROR(err); /* Write image to file. */ file_write_status = stbi_write_png(IMAGE_FILE, width, height, 4, output_image, width * 4); /* Give feedback. */ if (file_write_status) { fprintf(stdout, "\nImage saved in file '" IMAGE_FILE "'\n"); } else { ERROR_MSG_AND_EXIT("Unable to save image in file."); } /* Release host images. */ free(output_image); stbi_image_free(input_image); /* Release wrappers. */ ccl_image_destroy(img_in); ccl_image_destroy(img_out); ccl_sampler_destroy(smplr); ccl_program_destroy(prg); ccl_queue_destroy(queue); ccl_context_destroy(ctx); /* Check all wrappers have been destroyed. */ assert(ccl_wrapper_memcheck()); /* Terminate. */ return EXIT_SUCCESS; }
int main(int argc, char** argv) { try { std::vector<cl::Platform> platforms; cl::Platform::get(&platforms); std::vector<cl::Device> platformDevices; platforms[0].getDevices(CL_DEVICE_TYPE_GPU, &platformDevices); cl::Context context(platformDevices); auto contextDevices = context.getInfo<CL_CONTEXT_DEVICES>(); for (auto dev : contextDevices) { std::cout << "Using " << dev.getInfo<CL_DEVICE_NAME>() << std::endl; } std::ifstream programFile("mandelbrot.cl"); std::string programString(std::istreambuf_iterator<char>(programFile), (std::istreambuf_iterator<char>())); cl::Program::Sources source(1, std::make_pair(programString.c_str(), programString.length()+1)); cl::Program program(context, source); try { program.build(contextDevices); } catch (cl::Error e) { // FIXME may not be the device that failed std::cout << program.getBuildInfo<CL_PROGRAM_BUILD_LOG>(contextDevices[0]) << std::endl; } cl::Kernel mandelbrot(program, "mandelbrot"); // command queues std::vector<cl::CommandQueue> queues; for (auto device : contextDevices) { cl::CommandQueue queue(context, device, CL_QUEUE_PROFILING_ENABLE); queues.push_back(queue); } unsigned char* iteration_counts = new unsigned char[3500*2500]; auto start = std::chrono::high_resolution_clock::now(); // partition the "y" dimension int i = 0; int workItemsPerQueue = 2500/queues.size(); // FIXME requires work size to be evenly divisible by number of queues std::vector<cl::Buffer> outputs; for (auto queue : queues) { cl::NDRange offset(0, 0); //i*workItemsPerQueue); cl::NDRange global_size(3500, workItemsPerQueue); // storage for results per device cl_int err = CL_SUCCESS; cl::Buffer output(context, CL_MEM_WRITE_ONLY, (size_t)3500*workItemsPerQueue, (void*)NULL, &err); mandelbrot.setArg(0, output); mandelbrot.setArg(1, i*workItemsPerQueue); outputs.push_back(output); queue.enqueueNDRangeKernel(mandelbrot, offset, global_size); queue.enqueueBarrierWithWaitList(); std::cout << "enqueued range " << i*workItemsPerQueue << " of length " << workItemsPerQueue << std::endl; i++; } // read results unsigned char* results = new unsigned char[3500*2500]; std::vector<cl::Event> readWaitList; i = 0; for (auto queue : queues) { size_t offset = i*3500*workItemsPerQueue; cl::Event readDoneEvent; queue.enqueueReadBuffer(outputs[i], CL_FALSE, 0, 3500*workItemsPerQueue, &(results[offset]), NULL, &readDoneEvent); // NOTE: can't push onto vector until the event is valid, since it will be copied readWaitList.push_back(readDoneEvent); i++; } cl::Event::waitForEvents(readWaitList); auto end = std::chrono::high_resolution_clock::now(); std::chrono::duration<double> elapsed_seconds = end - start; std::cout << "computation took " << elapsed_seconds.count() << "s" << std::endl; stbi_write_png("mandelbrot_cl.png", 3500, 2500, 1, results, 3500); } catch (cl::Error e) { std::cout << e.what() << ": Error code " << e.err() << std::endl; } return 0; }
int generateFontMetadata (const char* ttfFilePath, const char* outputPNG, const char* outputMETADATA) { //fprintf(stderr, "TTF file %s \n", ttfFilePath); //fprintf(stderr, "PNG file %s \n", outputPNG); //fprintf(stderr, "META file %s \n", outputMETADATA); // Now we can initialise FreeType /* Check if the files are already there */ FILE* fpMeta = fopen(outputMETADATA, "r"); FILE* fpPng = fopen(outputPNG, "r"); if (fpMeta) { fclose (fpMeta); if (fpPng) { fclose (fpPng); return 0; } } FT_Library ft; if (FT_Init_FreeType (&ft)) { fprintf (stderr, "Could not init FreeType library\n"); return 1; } // load a font face from a file FT_Face face; if (FT_New_Face (ft, ttfFilePath, 0, &face)) { fprintf(stderr, "Could not open .ttf file\n"); return 1; } int atlas_dimension_px = 1024; // atlas size in pixels int atlas_columns = 16; // number of glyphs across atlas int padding_px = 6; // total space in glyph size for outlines int slot_glyph_size = 64; // glyph maximum size in pixels int atlas_glyph_px = 64 - padding_px; // leave some padding for outlines // Next we can open a file stream to write our atlas image to unsigned char* atlas_buffer = (unsigned char*)malloc ( atlas_dimension_px * atlas_dimension_px * 4 * sizeof (unsigned char) ); unsigned int atlas_buffer_index = 0; // I'll tell FreeType the maximum size of each glyph in pixels int grows[256]; // glyph height in pixels int gwidth[256]; // glyph width in pixels int gpitch[256]; // bytes per row of pixels int gymin[256]; // offset for letters that dip below baseline like g and y unsigned char* glyph_buffer[256] = { NULL }; // stored glyph images // set height in pixels width 0 height 48 (48x48) FT_Set_Pixel_Sizes (face, 0, atlas_glyph_px); for (int i = 33; i < 256; i++) { if (FT_Load_Char (face, i, FT_LOAD_RENDER)) { fprintf(stderr, "Could not load character %i\n", i); return 1; } // draw glyph image anti-aliased FT_Render_Glyph (face->glyph, FT_RENDER_MODE_NORMAL); // get dimensions of bitmap grows[i] = face->glyph->bitmap.rows; gwidth[i] = face->glyph->bitmap.width; gpitch[i] = face->glyph->bitmap.pitch; // copy glyph data into memory because it seems to be overwritten/lost later glyph_buffer[i] = (unsigned char*)malloc (grows[i] * gpitch[i]); memcpy ( glyph_buffer[i], face->glyph->bitmap.buffer, face->glyph->bitmap.rows * face->glyph->bitmap.pitch ); // get y-offset to place glyphs on baseline. this is in the bounding box FT_Glyph glyph; // a handle to the glyph image if (FT_Get_Glyph (face->glyph, &glyph)) { fprintf(stderr, "Could not get glyph handle %i\n", i); return 1; } // get bbox. "truncated" mode means get dimensions in pixels FT_BBox bbox; FT_Glyph_Get_CBox (glyph, FT_GLYPH_BBOX_TRUNCATE, &bbox); gymin[i] = bbox.yMin; } for (int y = 0; y < atlas_dimension_px; y++) { for (int x = 0; x < atlas_dimension_px; x++) { // work out which grid slot[col][row] we are in e.g out of 16x16 int col = x / slot_glyph_size; int row = y / slot_glyph_size; int order = row * atlas_columns + col; int glyph_index = order + 32; // an actual glyph bitmap exists for these indices if (glyph_index > 32 && glyph_index < 256) { // pixel indices within padded glyph slot area int x_loc = x % slot_glyph_size - padding_px / 2; int y_loc = y % slot_glyph_size - padding_px / 2; // outside of glyph dimensions use a transparent, black pixel (0,0,0,0) if (x_loc < 0 || y_loc < 0 || x_loc >= gwidth[glyph_index] || y_loc >= grows[glyph_index]) { atlas_buffer[atlas_buffer_index++] = 0; atlas_buffer[atlas_buffer_index++] = 0; atlas_buffer[atlas_buffer_index++] = 0; atlas_buffer[atlas_buffer_index++] = 0; } else { // this is 1, but it's safer to put it in anyway //int bytes_per_pixel = gwidth[glyph_index] / gpitch[glyph_index]; //int bytes_in_glyph = grows[glyph_index] * gpitch[glyph_index]; int byte_order_in_glyph = y_loc * gwidth[glyph_index] + x_loc; unsigned char colour[4]; colour[0] = colour[1] = colour[2] = colour[3] = glyph_buffer[glyph_index][byte_order_in_glyph]; // print byte from glyph atlas_buffer[atlas_buffer_index++] = glyph_buffer[glyph_index][byte_order_in_glyph]; atlas_buffer[atlas_buffer_index++] = glyph_buffer[glyph_index][byte_order_in_glyph]; atlas_buffer[atlas_buffer_index++] = glyph_buffer[glyph_index][byte_order_in_glyph]; atlas_buffer[atlas_buffer_index++] = glyph_buffer[glyph_index][byte_order_in_glyph]; } // write black in non-graphical ASCII boxes } else { atlas_buffer[atlas_buffer_index++] = 0; atlas_buffer[atlas_buffer_index++] = 0; atlas_buffer[atlas_buffer_index++] = 0; atlas_buffer[atlas_buffer_index++] = 0; } //endif } // endfor } // endfor // write meta-data file to go with atlas image std::ofstream myfile; myfile.open (outputMETADATA, std::ios::in | std::ios::out | std::ios::app | std::ios::binary); if (!myfile.is_open()) { free (atlas_buffer); return 1; } myfile << "// ascii_code prop_xMin prop_width prop_yMin prop_height prop_y_offset" << std::endl; // write an unique line for the 'space' character myfile << "32" << " " << std::fixed << std::setprecision( 6 ) << 0.0f << " " << 0.5 << " " << 0.0f << " " << 1.0 << " " << 0.0f << std::endl; // write a line for each regular character for (int i = 33; i < 256; i++) { int order = i - 32; int col = order % atlas_columns; int row = order / atlas_columns; float x_min = (float)(col * slot_glyph_size) / (float)atlas_dimension_px; float y_min = (float)(row * slot_glyph_size) / (float)atlas_dimension_px; myfile << std::fixed << std::setprecision( 6 ) << i << " " << x_min << " " << (float)(gwidth[i] + padding_px) / 64.0f << " " << y_min << " " << (grows[i] + padding_px) / 64.0f << " " << -((float)padding_px - (float)gymin[i]) / 64.0f << std::endl; } myfile.close(); // free that buffer of glyph info for (int i = 0; i < 256; i++) { if (NULL != glyph_buffer[i]) { free (glyph_buffer[i]); } } // use stb_image_write to write directly to png if (!stbi_write_png ( outputPNG, atlas_dimension_px, atlas_dimension_px, 4, atlas_buffer, 0 )) { fprintf (stderr, "ERROR: could not write file %s\n", outputPNG); } free (atlas_buffer); return 0; }
void Film::writeImage() { stbi_write_png(output_image.c_str(), width, height, comp, data, stride_in_bytes); }
void debugMostSimilarSamples(MFCC* templat, MFCC* palette, Waveform paletteAudio) { assert(palette->numMfccs > 0); int32_t* closestMatches = new int32_t[templat->numWindows]; for(int64_t windowIndex = 0; windowIndex < templat->numWindows; ++ windowIndex) { double bestSim = similarityIndex(palette, 0, templat, windowIndex); int32_t bestPaletteIndex = 0; for(int32_t i = 1; i < palette->numWindows; ++ i) { double thisSim = similarityIndex(palette, i, templat, windowIndex); if(thisSim < bestSim) { bestSim = thisSim; bestPaletteIndex = i; } } closestMatches[windowIndex] = bestPaletteIndex; } { assert(palette->params.frameStepMilliseconds < palette->params.frameLengthMilliseconds); Waveform mixture; int32_t windowLength = (palette->params.frameLengthMilliseconds * paletteAudio.mSampleRate) / 1000; int32_t windowStep = (palette->params.frameStepMilliseconds * paletteAudio.mSampleRate) / 1000; mixture.mNumSamples = templat->numWindows * windowStep + windowLength; mixture.mFloatSamples = new double[mixture.mNumSamples]; for(int64_t i = 0; i < mixture.mNumSamples; ++ i) { mixture.mFloatSamples[i] = 0; } mixture.mSampleRate = paletteAudio.mSampleRate; for(int64_t windowIndex = 0; windowIndex < templat->numWindows; ++ windowIndex) { for(int64_t windowSample = 0; windowSample < windowLength; ++ windowSample) { // Apply hanning window // Hooray for compiler optimizations double tau = 6.28318530717958647692528677; double numerator = tau * windowSample; double denominator = windowLength - 1; double hanning = 0.5 * (1.0 - std::cos(numerator / denominator)); mixture.mFloatSamples[windowIndex * windowStep + windowSample] += hanning * paletteAudio.mFloatSamples[closestMatches[windowIndex] * windowStep + windowSample]; } } writeWaveform("closest_matches.ogg", mixture); } { int width = templat->numWindows; int height = templat->numMfccs; if(width > 2048) width = 2048; char imageData[width * height * 3]; for(int pixelY = 0; pixelY < height; ++ pixelY) { for(int pixelX = 0; pixelX < width; ++ pixelX) { int frame = pixelX; int spectrum = (height - pixelY) - 1; { double power = normalized(palette->data[closestMatches[frame]][spectrum], -4, 18); RGB heat = colorrampSevenHeat(power); imageData[(pixelY * width + pixelX) * 3 ] = heat.RU8(); imageData[(pixelY * width + pixelX) * 3 + 1] = heat.GU8(); imageData[(pixelY * width + pixelX) * 3 + 2] = heat.BU8(); } } } stbi_write_png("closest_matches.png", width, height, 3, imageData, width * 3); } }
// check basename for texture, and try to return jpg or png file void CheckTexture(const char *baseName, String &textureFileName) { const char *ext = strrchr(baseName,'.'); // check if jpg exists textureFileName=baseName; if (!ext) { textureFileName+=".jpg"; if (ExistsFile(textureFileName.c_str())) return; } // check if png exists textureFileName=baseName; if (ext) // erase ext textureFileName.erase(textureFileName.size()-strlen(ext),strlen(ext)); textureFileName+=".png"; if (ExistsFile(textureFileName.c_str())) return; // check if tga exists textureFileName=baseName; if (ext) // erase ext textureFileName.erase(textureFileName.size()-strlen(ext),strlen(ext)); textureFileName+=".tga"; if (ExistsFile(textureFileName.c_str())) { // convert tga to png String outFileName=baseName; if (ext) // erase ext outFileName.erase(outFileName.size()-strlen(ext),strlen(ext)); outFileName+=".png"; // bmp.TGAToPNG(textureFileName.c_str(),outFileName.c_str()); int width, height, comp; unsigned char *data = stbi_load(textureFileName.c_str(), &width, &height, &comp , 0); stbi_write_png(outFileName.c_str(), width, height, comp, data, width*comp); stbi_image_free(data); textureFileName = outFileName; return; } // check if jpg exists textureFileName=baseName; if (ext) // erase ext textureFileName.erase(textureFileName.size()-strlen(ext),strlen(ext)); textureFileName+=".jpg"; if (ExistsFile(textureFileName.c_str())) return; printf("Texture file not found:'%s'\n",baseName); }
int main(int argc, char **argv) { int w,h; //test_ycbcr(); #if 0 // test hdr asserts for (h=0; h < 100; h += 2) for (w=0; w < 200; ++w) hdr_data[h][w][0] = (float) rand(), hdr_data[h][w][1] = (float) rand(), hdr_data[h][w][2] = (float) rand(); stbi_write_hdr("output/test.hdr", 200,200,3,hdr_data[0][0]); #endif if (argc > 1) { int i, n; for (i=1; i < argc; ++i) { int res; int w2,h2,n2; unsigned char *data; printf("%s\n", argv[i]); res = stbi_info(argv[1], &w2, &h2, &n2); data = stbi_load(argv[i], &w, &h, &n, 4); if (data) free(data); else printf("Failed &n\n"); data = stbi_load(argv[i], &w, &h, 0, 1); if (data) free(data); else printf("Failed 1\n"); data = stbi_load(argv[i], &w, &h, 0, 2); if (data) free(data); else printf("Failed 2\n"); data = stbi_load(argv[i], &w, &h, 0, 3); if (data) free(data); else printf("Failed 3\n"); data = stbi_load(argv[i], &w, &h, &n, 4); assert(data); assert(w == w2 && h == h2 && n == n2); assert(res); if (data) { char fname[512]; stb_splitpath(fname, argv[i], STB_FILE); stbi_write_png(stb_sprintf("output/%s.png", fname), w, h, 4, data, w*4); stbi_write_bmp(stb_sprintf("output/%s.bmp", fname), w, h, 4, data); stbi_write_tga(stb_sprintf("output/%s.tga", fname), w, h, 4, data); stbi_write_png_to_func(dummy_write,0, w, h, 4, data, w*4); stbi_write_bmp_to_func(dummy_write,0, w, h, 4, data); stbi_write_tga_to_func(dummy_write,0, w, h, 4, data); free(data); } else printf("FAILED 4\n"); } } else { int i, nope=0; #ifdef PNGSUITE_PRIMARY char **files = stb_readdir_files("pngsuite/primary"); #else char **files = stb_readdir_files("images"); #endif for (i=0; i < stb_arr_len(files); ++i) { int n; char **failed = NULL; unsigned char *data; printf("."); //printf("%s\n", files[i]); data = stbi_load(files[i], &w, &h, &n, 0); if (data) free(data); else stb_arr_push(failed, "&n"); data = stbi_load(files[i], &w, &h, 0, 1); if (data) free(data); else stb_arr_push(failed, "1"); data = stbi_load(files[i], &w, &h, 0, 2); if (data) free(data); else stb_arr_push(failed, "2"); data = stbi_load(files[i], &w, &h, 0, 3); if (data) free(data); else stb_arr_push(failed, "3"); data = stbi_load(files[i], &w, &h, 0, 4); if (data) ; else stb_arr_push(failed, "4"); if (data) { char fname[512]; #ifdef PNGSUITE_PRIMARY int w2,h2; unsigned char *data2; stb_splitpath(fname, files[i], STB_FILE_EXT); data2 = stbi_load(stb_sprintf("pngsuite/primary_check/%s", fname), &w2, &h2, 0, 4); if (!data2) printf("FAILED: couldn't load 'pngsuite/primary_check/%s\n", fname); else { if (w != w2 || h != w2 || 0 != memcmp(data, data2, w*h*4)) { int x,y,c; if (w == w2 && h == h2) for (y=0; y < h; ++y) for (x=0; x < w; ++x) for (c=0; c < 4; ++c) assert(data[y*w*4+x*4+c] == data2[y*w*4+x*4+c]); printf("FAILED: %s loaded but didn't match PRIMARY_check 32-bit version\n", files[i]); } free(data2); } #else stb_splitpath(fname, files[i], STB_FILE); stbi_write_png(stb_sprintf("output/%s.png", fname), w, h, 4, data, w*4); #endif free(data); } if (failed) { int j; printf("FAILED: "); for (j=0; j < stb_arr_len(failed); ++j) printf("%s ", failed[j]); printf(" -- %s\n", files[i]); } } printf("Tested %d files.\n", i); } return 0; }
void writeTextureToPng(int textureWidth, int textureHeight, const char* fileName, int numComponents) { GLuint err; err = glGetError(); b3Assert(err==GL_NO_ERROR); glPixelStorei(GL_PACK_ALIGNMENT,4); glReadBuffer(GL_NONE); float* orgPixels = (float*)malloc(textureWidth*textureHeight*numComponents*4); char* pixels = (char*)malloc(textureWidth*textureHeight*numComponents*4); glReadPixels(0,0,textureWidth, textureHeight, GL_DEPTH_COMPONENT, GL_FLOAT, orgPixels); err = glGetError(); b3Assert(err==GL_NO_ERROR); for (int j=0;j<textureHeight;j++) { for (int i=0;i<textureWidth;i++) { float val = orgPixels[(j*textureWidth+i)]; if (val!=1.f) { //printf("val[%d,%d]=%f\n", i,j,val); } pixels[(j*textureWidth+i)*numComponents]=orgPixels[(j*textureWidth+i)]*255.f; pixels[(j*textureWidth+i)*numComponents+1]=0.f;//255.f; pixels[(j*textureWidth+i)*numComponents+2]=0.f;//255.f; pixels[(j*textureWidth+i)*numComponents+3]=255; //pixels[(j*textureWidth+i)*+1]=val; //pixels[(j*textureWidth+i)*numComponents+2]=val; //pixels[(j*textureWidth+i)*numComponents+3]=255; } /* pixels[(j*textureWidth+j)*numComponents]=255; pixels[(j*textureWidth+j)*numComponents+1]=0; pixels[(j*textureWidth+j)*numComponents+2]=0; pixels[(j*textureWidth+j)*numComponents+3]=255; */ } if (0) { //swap the pixels unsigned char tmp; for (int j=0;j<textureHeight/2;j++) { for (int i=0;i<textureWidth;i++) { for (int c=0;c<numComponents;c++) { tmp = pixels[(j*textureWidth+i)*numComponents+c]; pixels[(j*textureWidth+i)*numComponents+c]= pixels[((textureHeight-j-1)*textureWidth+i)*numComponents+c]; pixels[((textureHeight-j-1)*textureWidth+i)*numComponents+c] = tmp; } } } } stbi_write_png(fileName, textureWidth,textureHeight, numComponents, pixels, textureWidth*numComponents); free(pixels); }
bool ImageWriter::WritePNG(const std::string& sFilename, unsigned char* buffer_rbga, int width, int height) { return (stbi_write_png(sFilename.c_str(), width, height, 4, buffer_rbga, 4*width) == 0); }
void WriteImageToFile(std::string out_filename, T img) { assert( (img->BitDepth() & 7) == 0); stbi_write_png(out_filename.c_str(), img->Width(), img->Height(), img->kNumChannels, img->Width() * (img->BitDepth()/8) ); }
void ImageWriter::writeSurface(const string& fn, IDirect3DSurface9* surf, bool discardAlpha) { //{ // D3DSURFACE_DESC desc, tdesc; // surf->GetDesc(&desc); // tempSurf->GetDesc(&tdesc); // SDLOG(-1, "Screenshot surface: %s\n - tmp surface: %s\n", D3DSurfaceDescToString(desc), D3DSurfaceDescToString(tdesc)); //} // Octagon screenshot mode if(Settings::get().getMaxScreenshotParallelism() == -1) { string fnc = fn; boost::algorithm::replace_first(fnc, ".png", ".bmp"); if(D3DXSaveSurfaceToFile(fnc.c_str(), D3DXIFF_BMP, surf, NULL, NULL) != D3D_OK) { Console::get().add("Failed saving screenshot! (D3DX)"); } return; } // wait for processing if maximum degree of parallelism reached if(futures.size() > 0 && static_cast<int>(futures.size()) > Settings::get().getMaxScreenshotParallelism()) { auto& f = futures.front(); if(f.valid()) f.wait(); futures.pop(); } // get image data into buffer D3DSURFACE_DESC desc; surf->GetDesc(&desc); RECT r; r.left = 0; r.top = 0; r.right = desc.Width; r.bottom = desc.Height; if(Settings::get().getConstrainInjectedRT()) { if(r.right > wmax) r.right = wmax; if(r.bottom > hmax) r.bottom = hmax; } HRESULT hr = device9->StretchRect(surf, &r, tempSurf, &r, D3DTEXF_NONE); if(hr != D3D_OK) { Console::get().add("Failed taking screenshot! (StretchRect)"); return; } D3DLOCKED_RECT lockedR; if(tempSurf->LockRect(&lockedR, &r, D3DLOCK_READONLY) == D3D_OK) { BYTE* buffer = new (std::nothrow) BYTE[lockedR.Pitch*r.bottom]; if(buffer == nullptr) { Console::get().add("Failed taking screenshot! (could not allocate buffer memory)"); tempSurf->UnlockRect(); return; } memcpy(buffer, lockedR.pBits, lockedR.Pitch*r.bottom); INT pitch = lockedR.Pitch; tempSurf->UnlockRect(); // lambda performing image encoding and writing auto writer = [this, r, buffer, pitch, fn, discardAlpha] { for(int i = 0; i < pitch*r.bottom; i += 4) { // A8R8G8B8 --> (A)BGR BYTE tmp = buffer[i + 0]; buffer[i + 0] = buffer[i + 2]; buffer[i + 1] = buffer[i + 1]; buffer[i + 2] = tmp; if(discardAlpha) buffer[i + 3] = 255; } if(stbi_write_png(fn.c_str(), r.right, r.bottom, 4, buffer, pitch) == 0) { Console::get().add("Failed taking screenshot! (STBI)"); } delete[] buffer; }; if(Settings::get().getMaxScreenshotParallelism() > 0) { // perform image encoding and writing in parallel futures.push(std::async(writer)); } else { writer(); } } else { Console::get().add("Failed taking screenshot! (LockRect)"); } }