/* * main */ int main(int argc, char **argv) { struct prog_opts prog_opts; int i; struct image curr_img; /* configure defaults */ prog_opts.verbose_fl=0; prog_opts.tile_w=DEFAULT_W; prog_opts.tile_h=DEFAULT_H; prog_opts.out_bpp=DEFAULT_BPP; prog_opts.out_filename=DEFAULT_OUTFILE; /* load command-line configuration */ if (!parse_args(&prog_opts, argc, argv)) { return EXIT_FAILURE; } TRACE("opts: %ux%u@%u '%s'\n", prog_opts.tile_w, prog_opts.tile_h, prog_opts.out_bpp, prog_opts.out_filename); if (optind >= argc) { usage(); return EXIT_FAILURE; } if (optind+1 != argc) { fprintf(stderr, "Currently only supports exactly 1 input filename.\n"); usage(); return EXIT_FAILURE; } for (i=optind; i<argc; i++) { if (!load_png(argv[i], &curr_img)) { fprintf(stderr, "Could not load image '%s'\n", argv[i]); return EXIT_FAILURE; } if (!save_chr(prog_opts.out_filename, &curr_img, prog_opts.tile_w, prog_opts.tile_h)) { fprintf(stderr, "Could not save image '%s'\n", prog_opts.out_filename); return EXIT_FAILURE; } image_destroy(&curr_img); } return EXIT_SUCCESS; }
BITMAP *get_avatar(int uid) { unsigned char found = 0; avalist *cur = avatars; while(cur != NULL) { if(cur->id == uid) { found = 1; break; } cur = cur->next; } if(!found) { char request[256], pngfname[128]; BITMAP *ret; //CURL *curl_handle; avalist *newa; // http://www.bafsoft.net/acc_cache/user.php sprintf(request, "http://www.bafsoft.net/acc_cache/user.php?usr=%d&cmd=avapng", uid); sprintf(pngfname, "temp/%d.png", uid); printf("\nDownloading avatar for user #%d [%s]\n", uid, request); temp = fopen(pngfname, "wb"); curl_easy_setopt(curl_handle, CURLOPT_URL, request); curl_easy_perform(curl_handle); //curl_easy_cleanup(curl_handle); fclose(temp); newa = (avalist *)malloc(sizeof(avalist)); newa->id = uid; newa->bmp = load_png(pngfname, NULL); if(!newa->bmp) printf("Ack! WTF @ %s\n", pngfname); newa->next = NULL; cur = avatars; if(cur) { while(cur->next != NULL) cur = cur->next; cur->next = newa; cur = cur->next; } else avatars = cur = newa; } return cur->bmp; }
static int detect_image(const char *filepath, LCUI_Graph *out) /* 功能:检测图片格式,并解码图片 */ { int result = 1; if (result == 1) { result = load_png(filepath, out); } if (result == 1) { result = load_jpeg(filepath, out); } if (result == 1) { result = load_bmp(filepath, out); } return result; }
// Show the loading screen void loading_screen() { // Load the logo texture logo_tex = load_png("logotex.png", true, false, true); glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); glPushMatrix(); glLoadIdentity(); begin_fonts(); // Draw the background BIND_TEXTURE(0); glBegin(GL_TRIANGLE_STRIP); glColor3f(0.0f,0.0f,0.0f); // 0, 0.5f, 0.7f glVertex3f( 4, 3, -2); glVertex3f(-4, 3, -2); glColor3f(0, 0.4f, 0.7f); // 0, 0.2f, 0.3f glVertex3f( 4,-3, -2); glVertex3f(-4,-3, -2); glEnd(); // Draw the logo glEnable(GL_BLEND); BIND_TEXTURE(logo_tex); glTranslatef(0,1,-13); glColor3f(1,1,1); glBegin(GL_TRIANGLE_STRIP); glTexCoord2f(1,1); glVertex3f( 4, .5f, 0); glTexCoord2f(0,1); glVertex3f(-4, .5f, 0); glTexCoord2f(1,0); glVertex3f( 4,-.5f, 0); glTexCoord2f(0,0); glVertex3f(-4,-.5f, 0); glEnd(); // Draw the text glColor3f(1,1,0.5f); glprintf_center(font1, 0, 0, -1, -20, "...LOADING..."); end_fonts(); glPopMatrix(); // Flush and swap the buffers glFlush(); SDL_GL_SwapBuffers(); }
void create_png_texbind(char *file_name, GLuint *texbind, GLuint component, GLuint format) { int depth,spheretexw,spheretexh; char *spheretexdata; glGenTextures(1,texbind); load_png(file_name,&spheretexw,&spheretexh,&depth,&spheretexdata); glBindTexture(GL_TEXTURE_2D,*texbind); gluBuild2DMipmaps(GL_TEXTURE_2D, component, spheretexw, spheretexh, format, GL_UNSIGNED_BYTE, spheretexdata); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, options_tex_min_filter); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, options_tex_mag_filter); if(options_anisotrop && options_value_anisotrop > 0.0) { glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, options_value_anisotrop); } glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); free(spheretexdata); }
RoadMapImage roadmap_canvas_agg_load_image (const char *path, const char *file_name) { char *full_name = roadmap_path_join (path, file_name); RoadMapImage image; if ((strlen(file_name) > 4) && !strcasecmp (file_name + strlen(file_name) - 4, ".png")) { image = load_png (full_name); } else { image = load_bmp (full_name); } free (full_name); return image; }
GLuint Model::loadTexture(std::string fileName) { glPixelStorei(GL_UNPACK_ALIGNMENT, 1); GLuint tex; glGenTextures(1, &tex); glBindTexture(GL_TEXTURE_2D, tex); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); int w, h; GLubyte *pixels = (GLubyte *) load_png(fileName, &w, &h); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels); free(pixels); return tex; }
void loadimage(char *name, image* img) { if(img->reload == TRUE)//check if its a new image or the first load. { // Read image from file load_png( name, img); glGenTextures( 1, &img ->texid ); glBindTexture( GL_TEXTURE_2D, img ->texid ); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); glTexImage2D( GL_TEXTURE_2D, 0, img ->format, img ->width, img ->height, 0, img ->format, GL_UNSIGNED_BYTE, (void*) img->pixels ); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); img->reload = FALSE; } }
/**************************************************** Seabed functions ****************************************************/ bool initSeabed(Seabed *terrain, float size, float height, float displace, const char *texFile, const char *heightFile) { Image *image = load_png(heightFile); GLuint tex = texture_load(texFile); if(!image || !tex) { printf("Error: seabed file not loaded. \n"); return false; } terrain->image = image; terrain->tex = tex; terrain->scale = size; terrain->displacement = displace; terrain->height = height; return true; }
Texture *load_texture(const char *filename) { SDL_Surface *surface = load_png(filename); if(surface == NULL) errx(-1,"load_texture():\n!- cannot load '%s'", filename); Texture *texture = create_element((void **)&resources.textures, sizeof(Texture)); load_sdl_surf(surface, texture); free(surface->pixels); SDL_FreeSurface(surface); char *beg = strstr(filename, "gfx/") + 4; char *end = strrchr(filename, '.'); texture->name = malloc(end - beg + 1); memset(texture->name, 0, end-beg + 1); strncpy(texture->name, beg, end-beg); printf("-- loaded '%s' as '%s'\n", filename, texture->name); return texture; }
void init_graphic() { memset(&ctx, 0, sizeof(DrawCtx)); // alloc VSH Menu graphic buffers, generic based on canvas constants buf[0].addr = mem_alloc(CANVAS_W * CANVAS_H * sizeof(uint32_t)); // canvas buffer buf[1].addr = mem_alloc(CANVAS_W * CANVAS_H * sizeof(uint32_t)); // background buffer #ifdef HAVE_PNG_FONT // load font png Buffer font = load_png(PNG_FONT_PATH); ctx.font = font.addr; #endif // set drawing context ctx.canvas = buf[0].addr; ctx.bg = buf[1].addr; ctx.bg_color = 0xFF000000; // black, opaque ctx.fg_color = 0xFFFFFFFF; // white, opaque // get current display values offset = *(uint32_t*)0x60201104; // start offset of current framebuffer getDisplayPitch(&pitch, &unk1); // framebuffer pitch size h = getDisplayHeight(); // display height w = getDisplayWidth(); // display width // get x/y start coordinates for our canvas, always center canvas_x = (w - CANVAS_W) /2; canvas_y = (h - CANVAS_H) /2; // dump background, for alpha blending dump_bg(); // init first frame with background dump memcpy((uint8_t *)ctx.canvas, (uint8_t *)ctx.bg, CANVAS_W * CANVAS_H * sizeof(uint32_t)); }
/*********************************************************************** * load a png file * * int32_t idx = index of png, max 4 (0 - 3) * const char *path = path to png file ***********************************************************************/ int32_t load_png_bitmap(int32_t idx, const char *path) { if(idx > PNG_MAX) return -1; ctx.png[idx] = load_png(path); return 0; }
void ogl::texture::load_img(std::string name, std::map<int, vec4>& scale) { std::vector<GLubyte> pixels; // Load and parse the data file. size_t len; const void *buf = ::data->load(name, &len); if (buf) load_png(buf, len, pixels); ::data->free(name); // Initialize the OpenGL texture object. GLenum f = GL_RGBA; switch (c) { case 1: f = GL_LUMINANCE; case 2: f = GL_LUMINANCE_ALPHA; case 3: f = GL_RGB; } ogl::bind_texture(GL_TEXTURE_2D, GL_TEXTURE0, object); GLubyte *p = &pixels.front(); GLsizei ww = w; GLsizei hh = h; // Enumerate the mipmap levels. for (GLint l = 0; ww > 0 && hh > 0; l++) { std::map<int, vec4>::iterator it; // Set the scale for this mipmap. if ((it = scale.find(l)) == scale.end()) { glPixelTransferf(GL_RED_SCALE, 1.f); glPixelTransferf(GL_GREEN_SCALE, 1.f); glPixelTransferf(GL_BLUE_SCALE, 1.f); glPixelTransferf(GL_ALPHA_SCALE, 1.f); } else { glPixelTransferf(GL_RED_SCALE, GLfloat(it->second[0])); glPixelTransferf(GL_GREEN_SCALE, GLfloat(it->second[1])); glPixelTransferf(GL_BLUE_SCALE, GLfloat(it->second[2])); glPixelTransferf(GL_ALPHA_SCALE, GLfloat(it->second[3])); } // Copy the pixels. glTexImage2D(GL_TEXTURE_2D, l, f, ww, hh, 0, f, GL_UNSIGNED_BYTE, p); // Prepare for the next mipmap level. downsample(ww, hh, c, pixels); ww /= 2; hh /= 2; } // Initialize the default texture parameters. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); if (ogl::has_anisotropic) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, ogl::max_anisotropy); }
int main(int argc, char *argv[]) { if (argc != 2) { printf("Usage: %s file.cgl\n", argv[0]); exit(-1); } SDL_Surface *screen; SDL_Surface *gfx = load_gfx("data/GRAVITY.GFX"); if (!gfx) { fprintf(stderr, "read_gfx: %s\n", SDL_GetError()); abort(); } SDL_Surface *png = load_png("font.png"); if (!png) { fprintf(stderr, "load_png: %s\n", SDL_GetError()); abort(); } SDL_Surface *osd = load_png("osd.png"); if (!osd) { fprintf(stderr, "load_png: %s\n", SDL_GetError()); abort(); } struct cgl *cgl = read_cgl(argv[1], NULL); if (!cgl) { fprintf(stderr, "read_cgl: %s\n", SDL_GetError()); abort(); } cgl_preprocess(cgl); cg_init(cgl); make_collision_map(gfx, cmap); if (SDL_Init(SDL_INIT_VIDEO) != 0) { fprintf(stderr, "SDL failed: %s\n", SDL_GetError()); abort(); } screen = SDL_SetVideoMode(SCREEN_W, SCREEN_H, 0, MODE); gl_resize_viewport(screen->w, screen->h); struct texmgr *ttm = tm_request_texture(gfx); struct texmgr *fnt = tm_request_texture(png); struct texmgr *otm = tm_request_texture(osd); gl_init(cgl, ttm, fnt, otm); int t = SDL_GetTicks(), nt = t, time = t, fr = 0; running = 1; mouse = 0; SDL_Event e; while (running) { while (SDL_PollEvent(&e)) process_event(&e); time = SDL_GetTicks(); nt = time - t; cg_step(cgl, time / 1000.0); if (nt > 100) { printf("%d frames in %d ms - %.1f fps\n", gl.frame - fr, nt, (float)(gl.frame - fr) / nt * 1000); if (cgl->status == Lost) printf("Dead. Game over!"); if (cgl->status == Victory) printf("You won!"); fflush(stdout); t += nt; fr = gl.frame; } gl.cam.nx = cgl->ship->x + SHIP_W/2.0; gl.cam.ny = cgl->ship->y + SHIP_H/2.0; gl_update_window(time / 1000.0); } free_cgl(cgl); return 0; }
int WinMain() { #else int main() { #endif try { if(SDL_Init(SDL_INIT_VIDEO) < 0) { throw Game::SDLError(); } { int imgFlags = IMG_INIT_PNG; if(!(IMG_Init(imgFlags) & imgFlags)) { throw Game::SDLError(IMG_GetError()); } } if (TTF_Init() < 0) { throw Game::SDLError(TTF_GetError()); } if(Mix_OpenAudio(44100, MIX_DEFAULT_FORMAT, 2, 2048) < 0) { printf("Error starting SDL_Mix: %s\n", Mix_GetError()); } auto gs = std::make_shared<Game::sdl_info>("Letvezi", "art/font.ttf"); auto persistent = std::make_shared<Persistent>("user_info.dat"); if (persistent == NULL) throw std::runtime_error("Failed to create user settings object"); gs->loading_screen([persistent](auto& ch) { auto set_bg = [&ch](std::string file) { ch.push(std::tuple<std::string,std::function<void(Game::sdl_info&)>>( "background music", [file](auto& gs) { gs.set_background(file); } ) ); }; auto load_sfx = [&ch](std::string key, Game::SFX_ID xkey, std::string file) { ch.push( std::tuple<std::string,std::function<void(Game::sdl_info&)>>( key, [xkey,file](auto& gs) { gs.load_sfx(xkey,file); } ) ); }; auto load_png = [&ch](std::string key, Game::TextureID xkey, std::string file) { ch.push( std::tuple<std::string,std::function<void(Game::sdl_info&)>>( key, [xkey,file](auto& gs) { gs.load_png(xkey,file); } ) ); }; auto do_ = [&ch](std::string key, std::function<void()> fn) { ch.push( std::tuple<std::string,std::function<void(Game::sdl_info&)>>( key, [fn](auto&) { fn(); } )); }; set_bg("art/background.ogg"); load_png("bg_star" , Game::TEX_BackgroundStar , "art/img/bg_star.png" ); load_png("player" , Game::TEX_Player , "art/img/player.png" ); load_png("player_laser" , Game::TEX_PlayerLaser , "art/img/player_laser.png" ); load_png("player_life" , Game::TEX_PlayerLife , "art/img/player_life.png" ); load_png("player_shield" , Game::TEX_PlayerShield , "art/img/player_shield.png" ); load_png("enemy_1" , Game::TEX_Enemy1 , "art/img/enemy_1.png" ); load_png("enemy_2" , Game::TEX_Enemy2 , "art/img/enemy_2.png" ); load_png("enemy_3" , Game::TEX_Enemy3 , "art/img/enemy_3.png" ); load_png("enemy_boss" , Game::TEX_EnemyBoss , "art/img/enemy_boss.png" ); load_png("enemy_laser" , Game::TEX_EnemyLaser , "art/img/enemy_laser.png" ); load_png("enemy_boss_laser", Game::TEX_EnemyBossLaser , "art/img/enemy_boss_laser.png" ); load_png("enemy_boss_squad", Game::TEX_EnemyBossSquad , "art/img/enemy_boss_squad.png" ); load_png("powerup_shield" , Game::TEX_PowerupShield , "art/img/powerup_shield.png" ); load_png("powerup_bolt" , Game::TEX_PowerupBolt , "art/img/powerup_bolt.png" ); load_sfx("player_laser" , Game::SFX_PlayerLaser , "art/sfx/player_laser.ogg" ); load_sfx("shield_enabled" , Game::SFX_ShieldEnabled , "art/sfx/player_laser.ogg" ); do_("user info", [persistent]() { persistent->load(); }); }); Game::Resolution res = gs->get_current_res(); Letvezi::GameState::Type start_state = Letvezi::GameState::Type(persistent, gs, res, Letvezi::Position(res.width/2, res.height-70-gs->textures().at(Game::TEX_Player).height)); std::function<void(Conc::Chan<SDL_Event>&,Conc::Chan<Letvezi::Events::Type>&)> event_fn = Letvezi::event_handler; std::function<void(Conc::Chan<Letvezi::Events::Type>&,Conc::VarL<Letvezi::GameState::Type>&)> game_fn = Letvezi::game_handler; std::function<Game::LSit(Conc::VarL<Letvezi::GameState::Type>&,uint16_t)> render_fn = [gs](Conc::VarL<Letvezi::GameState::Type>& typ,uint16_t fps_rel) { return Letvezi::Render::handler_game(gs,typ,fps_rel); }; std::function<void(Conc::VarL<Letvezi::GameState::Type>&)> expensive_handler = Letvezi::Render::expensive_handler; gs->loop(event_fn, game_fn, expensive_handler, render_fn, start_state); persistent->save(); printf("Game over!\n"); } catch (Game::SDLError& err) { printf("SDL Error: %s\n", err.what()); } std::cout << "SDL_Quit()" << std::endl; SDL_Quit(); return 0; }
static FtkBitmap* ftk_image_png_decoder_decode(FtkImageDecoder* thiz, const char* filename) { return_val_if_fail(ftk_image_png_decoder_match(thiz, filename) == RET_OK, NULL); return load_png(filename); }
int main(int argc, char *argv[]) { BITMAP *fg; int depth = 16; const char *file; allegro_init(); install_keyboard(); switch (argc) { case 1: file = "alpha.png"; break; case 2: file = argv[1]; break; default: file = argv[1]; depth = atoi(argv[2]); break; } if (depth == 8) { allegro_message("Truecolour modes only.\n"); return 1; } set_color_depth(depth); if ((set_gfx_mode(GFX_AUTODETECT_WINDOWED, 640, 480, 0, 0) < 0) && (set_gfx_mode(GFX_AUTODETECT, 640, 480, 0, 0) < 0)) { allegro_message("Unable to set video mode (640x480x%d).\n", depth); return 1; } /* We can't lose the alpha channel when we load the image. */ set_color_conversion(COLORCONV_NONE); fg = load_png(file, NULL); if (!fg) { set_gfx_mode(GFX_TEXT, 0, 0, 0, 0); allegro_message("Unable to load alpha.png\n"); return 1; } acquire_screen(); toilet(screen); /* Enable alpha transparency, then draw onto the screen. */ set_alpha_blender(); draw_trans_sprite(screen, fg, (SCREEN_W - fg->w) / 2, (SCREEN_H - fg->h) / 2); release_screen(); /* Ooh, ahh. */ readkey(); destroy_bitmap(fg); return 0; }
void load_resources() { rec_btn = load_png("resources/32/player_record.png"); rec_btn_ds = load_png("resources/32/player_record_disabled.png"); stop_btn = load_png("resources/32/player_stop.png"); play_btn = load_png("resources/32/player_play.png"); play_btn_ds = load_png("resources/32/player_play_disabled.png"); pause_btn = load_png("resources/32/player_pause.png"); vol_1 = load_png("resources/32/Volume_1.png"); vol_2 = load_png("resources/32/Volume_2.png"); vol_3 = load_png("resources/32/Volume_3.png"); vol_mute = load_png("resources/32/Volume_Mute.png"); vol_out = load_png("resources/32/Volume_Not_Running.png"); font_10 = TTF_OpenFont("resources/font/UbuntuMono-R.ttf", 10); font_28 = TTF_OpenFont("resources/font/Ubuntu-L.ttf", 48); if (!font_10 || !font_28) { log(FATAL, "Cannot load 'UbuntuMono-R.ttf'."); } }
// The good old main() int main(int argc, char *argv[]) { // Initialize SDL and OpenGL init_sdl_and_gl(); // Initialize FMOD init_mixer(); // Load fonts build_font_list(); font1 = load_png("fonts.png", true, false, true); // Show the loading screen loading_screen(); // Find the level files find_levels(); // Load textures font_num = load_png("fonts_num.png", true, false, true); load_bgrounds(); load_players(); load_enemies(); load_bonus(); load_maptex(); load_bombs(); load_particles(); load_teleports(); load_traps(); load_wisps(); load_potatoman(); load_icons(); load_menus(); // Add timer to run 60 fps start_timer(60); // Menu logic int ans = show_menu(MENU_ID_MAIN); while(ans != MENU_EXIT) { // Start the game? if(ans == MENU_SINGLEPLAY) // Single player start_game(); else if(ans == MENU_MULTIPLAY) // Two players start_game(true); // Show the menu again ans = show_menu(MENU_ID_MAIN); } // Destroy timer kill_timer(); // Free stuff delete_font_list(); kill_particles(); // Kill SDL SDL_Quit(); // Close the pakfile pakfile.close_mpk(); // Close the FMOD if(music_mod){ Mix_HaltMusic(); Mix_FreeMusic(music_mod); } Mix_CloseAudio(); // Save the config save_config(get_config_location(true), &config); return 0; }
// Load the menu textures void load_menus() { button_tex = load_png("menubut.png", true, false, true); button_tex2 = load_png("menubut2.png", true, false, true); menu_bg = load_jpg("menubg.jpg", false, true, true); }
/* Usage: spritepack outfile infile1 infile2 ... */ int main(int argc, char** argv) { /* Buffer to hold img_t*'s for the input images */ img_t** images = malloc((argc-2) * sizeof(img_t*)); /* Loop over the program arguments, decoding input PNGs and * creating img_t*'s for them */ int i; for (i = 0; i < argc-2; ++i) { images[i] = load_png(argv[i+2]); autotrim(images[i]); } /* Sort the images, because pack_rects expects input in sorted order */ qsort(images, argc-2, sizeof(img_t*), image_comparator); /* Create a proxy array of rectangles, which pack_rects will use as input. * Note that the indexing matches the indexing into the images array for * easy correspondence. */ unsigned biggest_width = 0; unsigned width_sum = 0; unsigned* rects = malloc(2 * (argc-2) * sizeof(unsigned)); for (i = 0; i < argc-2; ++i) { rects[2*i] = images[i]->w; rects[2*i+1] = images[i]->h; if (images[i]->w > biggest_width) biggest_width = images[i]->w; width_sum += images[i]->w; } if (width_sum > 2048) width_sum = 2048; /* Explore all valid widths to find the most efficient packing. */ unsigned best_MP = 0, max_x, max_y; unsigned* ret; unsigned curr_width; for (curr_width = biggest_width; curr_width <= width_sum; ++curr_width) { unsigned curr_height; unsigned* new_ret = pack_rects(rects, argc-2, curr_width, &curr_height); if (curr_height > 2048) { free(new_ret); continue; } if (best_MP == 0 || curr_width * curr_height < best_MP) { max_x = curr_width; max_y = curr_height; ret = new_ret; best_MP = curr_width * curr_height; } else free(new_ret); } // Copy the data returned by the packer back into the img_t structures. for (i = 0; i < argc-2; ++i) { images[i]->offset_x = ret[2*i]; images[i]->offset_y = max_y - ret[2*i+1] - images[i]->h; } free(ret); // Sort the images by filename again qsort(images, argc-2, sizeof(img_t*), filename_comparator); /* Spew input image offsets */ png_text comments; comments.compression = PNG_TEXT_COMPRESSION_zTXt; comments.key = "sprite"; // Setup the comments string for printf'ing. unsigned text_space = 2 * (argc-1) + 1; comments.text = malloc(text_space); comments.text[0] = 0; char* num_sprites; asprintf(&num_sprites, "%d", argc-2); while (strlen(comments.text) + strlen(num_sprites) + 1 > text_space) { text_space *= 2; comments.text = realloc(comments.text, text_space); } comments.text = strncat(comments.text, num_sprites, strlen(num_sprites)); for (i = 0; i < argc-2; ++i) { char* output; asprintf(&output, ", %d, %d, %d, %d, %d, %d", /* top left corner */ images[i]->offset_x, images[i]->offset_y, /* bottom right corner */ images[i]->offset_x + images[i]->w, images[i]->offset_y + images[i]->h, /* center offset */ images[i]->center_x, images[i]->center_y); //printf("%s\n", output); while (strlen(comments.text) + strlen(output) + 1 > text_space) { text_space *= 2; comments.text = realloc(comments.text, text_space); } comments.text = strncat(comments.text, output, strlen(output)); } comments.text_length = strlen(comments.text); /* Allocate the output image */ unsigned char** out_image = malloc(max_y * sizeof(unsigned char*)); for (i = 0; i < (int)max_y; ++i) out_image[i] = calloc(4 * max_x, sizeof(unsigned char)); /* Blit each input image into the output image at the offset determined * by the packing. This is a bit complicated, since the decoded pixels * are indexed from the top-left, while the packing uses bottom-left indexing */ for (i = 0; i < argc-2; ++i) { unsigned off_x = images[i]->offset_x; unsigned off_y = images[i]->offset_y; unsigned y; for (y = 0; y < images[i]->h; ++y) { unsigned y_pix = off_y + y; memcpy(out_image[y_pix] + 4 * off_x, images[i]->pixels[images[i]->top + y] + 4 * images[i]->left, 4 * images[i]->w); } } /* Encode and output the output image */ write_png(argv[1], max_x, max_y, out_image, &comments); return 0; }
static inline Util::PngImageHolder load_png(const std::string& filename) { return load_png(filename.data()); }