diff --git a/source/animated_sprite.cpp b/source/animated_sprite.cpp index 8549121..e172259 100644 --- a/source/animated_sprite.cpp +++ b/source/animated_sprite.cpp @@ -1,10 +1,10 @@ #include "animated_sprite.h" -#include // for copy -#include // for basic_ostream, operator<<, basic_istream, basic... -#include // for cout -#include // for back_insert_iterator, back_inserter -#include // for basic_stringstream -#include "texture.h" // for Texture +#include // para copy +#include // para basic_ostream, operator<<, basic_istream, basic... +#include // para cout +#include // para back_insert_iterator, back_inserter +#include // para basic_stringstream +#include "texture.h" // para Texture #include "utils.h" // Carga las animaciones en un vector(Animations) desde un fichero @@ -106,65 +106,18 @@ void AnimatedSprite::animate() } } -// Obtiene el número de frames de la animación actual -int AnimatedSprite::getNumFrames() -{ - return (int)animations_[current_animation_].frames.size(); -} - -// Establece el frame actual de la animación -void AnimatedSprite::setCurrentFrame(int num) -{ - // Descarta valores fuera de rango - if (num >= (int)animations_[current_animation_].frames.size()) - { - num = 0; - } - - // Cambia el valor de la variable - animations_[current_animation_].current_frame = num; - animations_[current_animation_].counter = 0; - - // Escoge el frame correspondiente de la animación - setSpriteClip(animations_[current_animation_].frames[animations_[current_animation_].current_frame]); -} - -// Establece el valor del contador -void AnimatedSprite::setAnimationCounter(const std::string &name, int num) -{ - animations_[getIndex(name)].counter = num; -} - -// Establece la velocidad de una animación -void AnimatedSprite::setAnimationSpeed(const std::string &name, int speed) -{ - animations_[getIndex(name)].counter = speed; -} - // Establece la velocidad de una animación void AnimatedSprite::setAnimationSpeed(int index, int speed) { animations_[index].counter = speed; } -// Establece si la animación se reproduce en bucle -void AnimatedSprite::setAnimationLoop(const std::string &name, int loop) -{ - animations_[getIndex(name)].loop = loop; -} - // Establece si la animación se reproduce en bucle void AnimatedSprite::setAnimationLoop(int index, int loop) { animations_[index].loop = loop; } -// Establece el valor de la variable -void AnimatedSprite::setAnimationCompleted(const std::string &name, bool value) -{ - animations_[getIndex(name)].completed = value; -} - // OLD - Establece el valor de la variable void AnimatedSprite::setAnimationCompleted(int index, bool value) { @@ -222,21 +175,6 @@ void AnimatedSprite::update() MovingSprite::update(); } -// Establece el rectangulo para un frame de una animación -void AnimatedSprite::setAnimationFrames(Uint8 index_animation, Uint8 index_frame, int x, int y, int w, int h) -{ - animations_[index_animation].frames.push_back({x, y, w, h}); -} - -// OLD - Establece el contador para todas las animaciones -void AnimatedSprite::setAnimationCounter(int value) -{ - for (auto &a : animations_) - { - a.counter = value; - } -} - // Reinicia la animación void AnimatedSprite::resetAnimation() { diff --git a/source/animated_sprite.h b/source/animated_sprite.h index 1917f4c..40c691b 100644 --- a/source/animated_sprite.h +++ b/source/animated_sprite.h @@ -1,11 +1,11 @@ #pragma once -#include // for SDL_Rect -#include // for Uint8 -#include // for shared_ptr -#include // for string -#include // for vector -#include "moving_sprite.h" // for MovingSprite +#include // para SDL_Rect +#include // para Uint8 +#include // para shared_ptr +#include // para string +#include // para vector +#include "moving_sprite.h" // para MovingSprite class Texture; struct Animation @@ -52,25 +52,15 @@ public: // Actualiza las variables del objeto void update() override; - // Obtiene el número de frames de la animación actual - int getNumFrames(); - - // Establece el frame actual de la animación - void setCurrentFrame(int num); - - // Establece el valor del contador - void setAnimationCounter(const std::string &name, int num); - // Establece la velocidad de una animación - void setAnimationSpeed(const std::string &name, int speed); void setAnimationSpeed(int index, int speed); // Establece el frame al que vuelve la animación al finalizar - void setAnimationLoop(const std::string &name, int loop); + //void setAnimationLoop(const std::string &name, int loop); void setAnimationLoop(int index, int loop); // Establece el valor de la variable - void setAnimationCompleted(const std::string &name, bool value); + //void setAnimationCompleted(const std::string &name, bool value); void setAnimationCompleted(int index, bool value); // Comprueba si ha terminado la animación @@ -87,12 +77,6 @@ public: void setCurrentAnimation(const std::string &name = "default"); void setCurrentAnimation(int index = 0); - // OLD - Establece el rectangulo para un frame de una animación - void setAnimationFrames(Uint8 index_animation, Uint8 index_frame, int x, int y, int w, int h); - - // OLD - Establece el contador para todas las animaciones - void setAnimationCounter(int value); - // Reinicia la animación void resetAnimation(); }; \ No newline at end of file diff --git a/source/asset.cpp b/source/asset.cpp index 8091181..1a5575b 100644 --- a/source/asset.cpp +++ b/source/asset.cpp @@ -1,11 +1,12 @@ #include "asset.h" #include "utils.h" -#include // for SDL_RWFromFile, SDL_RWclose, SDL_RWops -#include // for SDL_max -#include // for size_t -#include // for basic_ostream, operator<<, cout, endl +#include // para SDL_RWFromFile, SDL_RWclose, SDL_RWops +#include // para SDL_max +#include // para size_t +#include // para basic_ostream, operator<<, cout, endl #include #include +#include // Para std::find_if // [SINGLETON] Hay que definir las variables estáticas, desde el .h sólo la hemos declarado Asset *Asset::asset_ = nullptr; @@ -38,16 +39,21 @@ void Asset::add(const std::string &file, AssetType type, bool required, bool abs // Devuelve la ruta completa a un fichero a partir de una cadena std::string Asset::get(const std::string &text) const { - for (const auto &f : file_list_) - { - if (getFileName(f.file) == text) - { - return f.file; - } - } + auto it = std::find_if(file_list_.begin(), file_list_.end(), + [&text, this](const auto &f) + { + return getFileName(f.file) == text; + }); - std::cout << "Warning: file " << text.c_str() << " not found" << std::endl; - return ""; + if (it != file_list_.end()) + { + return it->file; + } + else + { + std::cout << "Warning: file " << text << " not found" << std::endl; + return ""; + } } // Comprueba que existen todos los elementos diff --git a/source/asset.h b/source/asset.h index d863bcc..0dad8a2 100644 --- a/source/asset.h +++ b/source/asset.h @@ -1,7 +1,7 @@ #pragma once -#include // for string, basic_string -#include // for vector +#include // para string, basic_string +#include // para vector #include "utils.h" enum class AssetType : int diff --git a/source/background.cpp b/source/background.cpp index e886fd4..b088f00 100644 --- a/source/background.cpp +++ b/source/background.cpp @@ -1,14 +1,14 @@ #include "background.h" -#include // for SDL_BLENDMODE_BLEND -#include // for SDL_PIXELFORMAT_RGBA8888 -#include // for clamp, max -#include "asset.h" // for Asset -#include "moving_sprite.h" // for MovingSprite -#include "param.h" // for param -#include "resource.h" // for Resource +#include // para SDL_BLENDMODE_BLEND +#include // para SDL_PIXELFORMAT_RGBA8888 +#include // para clamp, max +#include "asset.h" // para Asset +#include "moving_sprite.h" // para MovingSprite +#include "param.h" // para param +#include "resource.h" // para Resource #include "screen.h" -#include "sprite.h" // for Sprite -#include "texture.h" // for Texture +#include "sprite.h" // para Sprite +#include "texture.h" // para Texture // Constructor Background::Background() diff --git a/source/background.h b/source/background.h index 7d472e5..d525b0f 100644 --- a/source/background.h +++ b/source/background.h @@ -1,9 +1,9 @@ #pragma once -#include // for SDL_Rect -#include // for SDL_Renderer, SDL_Texture -#include // for unique_ptr, shared_ptr -#include "utils.h" // for Color +#include // para SDL_Rect +#include // para SDL_Renderer, SDL_Texture +#include // para unique_ptr, shared_ptr +#include "utils.h" // para Color class MovingSprite; class Sprite; class Texture; diff --git a/source/balloon.cpp b/source/balloon.cpp index 76d99a7..faeb9d3 100644 --- a/source/balloon.cpp +++ b/source/balloon.cpp @@ -1,10 +1,10 @@ #include "balloon.h" -#include // for abs -#include "animated_sprite.h" // for SpriteAnimated -#include "moving_sprite.h" // for MovingSprite -#include "param.h" // for param -#include "sprite.h" // for Sprite -#include "texture.h" // for Texture +#include // para abs +#include "animated_sprite.h" // para SpriteAnimated +#include "moving_sprite.h" // para MovingSprite +#include "param.h" // para param +#include "sprite.h" // para Sprite +#include "texture.h" // para Texture // Constructor Balloon::Balloon(float x, float y, Uint8 kind, float vel_x, float speed, Uint16 creation_timer, std::shared_ptr texture, const std::vector &animation) diff --git a/source/balloon.h b/source/balloon.h index ed93dd0..98ff581 100644 --- a/source/balloon.h +++ b/source/balloon.h @@ -1,11 +1,11 @@ #pragma once -#include // for Uint8, Uint16, Uint32 -#include // for shared_ptr, unique_ptr -#include // for string -#include // for vector -#include "animated_sprite.h" // for SpriteAnimated -#include "utils.h" // for Circle +#include // para Uint8, Uint16, Uint32 +#include // para shared_ptr, unique_ptr +#include // para string +#include // para vector +#include "animated_sprite.h" // para SpriteAnimated +#include "utils.h" // para Circle class Texture; // Cantidad de elementos del vector con los valores de la deformación del globo al rebotar diff --git a/source/balloon_formations.cpp b/source/balloon_formations.cpp index 8ad8739..7370078 100644 --- a/source/balloon_formations.cpp +++ b/source/balloon_formations.cpp @@ -1,7 +1,7 @@ #include "balloon_formations.h" -#include "balloon.h" // for BALLOON_VELX_NEGATIVE, BALLOON_VELX_POSITIVE -#include "param.h" // for param -#include "utils.h" // for ParamGame, Param, Zone, BLOCK +#include "balloon.h" // para BALLOON_VELX_NEGATIVE, BALLOON_VELX_POSITIVE +#include "param.h" // para param +#include "utils.h" // para ParamGame, Param, Zone, BLOCK // Constructor BalloonFormations::BalloonFormations() diff --git a/source/bullet.cpp b/source/bullet.cpp index e5d0313..4b7d6d1 100644 --- a/source/bullet.cpp +++ b/source/bullet.cpp @@ -1,7 +1,7 @@ #include "bullet.h" -#include // for unique_ptr, make_unique, shared_ptr -#include "param.h" // for param -#include "sprite.h" // for Sprite +#include // para unique_ptr, make_unique, shared_ptr +#include "param.h" // para param +#include "sprite.h" // para Sprite class Texture; constexpr int BULLET_WIDTH = 12; diff --git a/source/bullet.h b/source/bullet.h index 45c20ae..c23025a 100644 --- a/source/bullet.h +++ b/source/bullet.h @@ -1,10 +1,10 @@ #pragma once -#include // for SDL_Rect -#include // for Uint8 -#include // for shared_ptr, unique_ptr -#include "sprite.h" // for Sprite -#include "utils.h" // for Circle +#include // para SDL_Rect +#include // para Uint8 +#include // para shared_ptr, unique_ptr +#include "sprite.h" // para Sprite +#include "utils.h" // para Circle class Texture; // Enumeración para los diferentes tipos de balas diff --git a/source/dbgtxt.cpp b/source/dbgtxt.cpp index c654dcc..f8d1d74 100644 --- a/source/dbgtxt.cpp +++ b/source/dbgtxt.cpp @@ -1,7 +1,7 @@ #include "dbgtxt.h" -#include // for SDL_Rect -#include // for SDL_RWFromMem -#include // for SDL_LoadBMP_RW +#include // para SDL_Rect +#include // para SDL_RWFromMem +#include // para SDL_LoadBMP_RW namespace { diff --git a/source/dbgtxt.h b/source/dbgtxt.h index b44f31d..f62ff53 100644 --- a/source/dbgtxt.h +++ b/source/dbgtxt.h @@ -1,7 +1,7 @@ #pragma once -#include // for SDL_Renderer -#include // for Uint8 +#include // para SDL_Renderer +#include // para Uint8 void dbg_init(SDL_Renderer *renderer); void dbg_print(int x, int y, const char *text, Uint8 r, Uint8 g, Uint8 b); diff --git a/source/define_buttons.cpp b/source/define_buttons.cpp index b61760c..b1db147 100644 --- a/source/define_buttons.cpp +++ b/source/define_buttons.cpp @@ -1,12 +1,12 @@ #include "define_buttons.h" -#include // for move -#include "input.h" // for Input, InputType -#include "lang.h" // for getText -#include "options.h" // for options -#include "param.h" // for param -#include "section.h" // for Name, Options, name, options -#include "text.h" // for Text -#include "utils.h" // for OptionsController, Options, Param, ParamGame +#include // para move +#include "input.h" // para Input, InputType +#include "lang.h" // para getText +#include "options.h" // para options +#include "param.h" // para param +#include "section.h" // para Name, Options, name, options +#include "text.h" // para Text +#include "utils.h" // para OptionsController, Options, Param, ParamGame // Constructor DefineButtons::DefineButtons(std::unique_ptr text_) diff --git a/source/define_buttons.h b/source/define_buttons.h index bd1dd29..7ad27f6 100644 --- a/source/define_buttons.h +++ b/source/define_buttons.h @@ -1,10 +1,10 @@ #pragma once -#include // for SDL_ControllerButtonEvent -#include // for SDL_GameControllerButton -#include // for shared_ptr, unique_ptr -#include // for string -#include // for vector +#include // para SDL_ControllerButtonEvent +#include // para SDL_GameControllerButton +#include // para shared_ptr, unique_ptr +#include // para string +#include // para vector class Input; class Text; enum class InputType : int; diff --git a/source/director.cpp b/source/director.cpp index 6d9e522..860d787 100644 --- a/source/director.cpp +++ b/source/director.cpp @@ -1,47 +1,47 @@ #include "director.h" -#include // for SDL_Init, SDL_Quit, SDL_INIT_EV... -#include // for AUDIO_S16 -#include // for SDL_BLENDMODE_BLEND -#include // for SDL_GetError -#include // for SDL_CONTROLLER_BUTTON_B, SDL_CO... -#include // for SDL_SetHint, SDL_HINT_RENDER_DR... -#include // for SDL_SCANCODE_0, SDL_SCANCODE_DOWN -#include // for SDL_bool, Uint32 -#include // for SDL_GetTicks -#include // for system -#include // for errno, EEXIST, EACCES, ENAMETOO... -#include // for printf, perror -#include // for strcmp -#include // for mkdir, stat, S_IRWXU -#include // for getuid -#include // for exit, EXIT_FAILURE, rand, srand -#include // for basic_ostream, operator<<, cout -#include // for make_unique, unique_ptr -#include // for operator+, allocator, char_traits -#include "asset.h" // for Asset, AssetType -#include "dbgtxt.h" // for dbg_init -#include "game.h" // for Game, GAME_MODE_DEMO_OFF, GAME_... -#include "global_inputs.h" // for init -#include "hiscore_table.h" // for HiScoreTable -#include "input.h" // for Input, InputType -#include "instructions.h" // for Instructions -#include "intro.h" // for Intro -#include "jail_audio.h" // for JA_LoadMusic, JA_LoadSound, JA_... -#include "lang.h" // for Code, loadFromFile -#include "logo.h" // for Logo -#include "manage_hiscore_table.h" // for ManageHiScoreTable -#include "notifier.h" // for Notifier -#include "on_screen_help.h" // for OnScreenHelp -#include "options.h" // for options, loadOptionsFile, saveO... -#include "param.h" // for param, loadParamsFromFile +#include // para SDL_Init, SDL_Quit, SDL_INIT_EV... +#include // para AUDIO_S16 +#include // para SDL_BLENDMODE_BLEND +#include // para SDL_GetError +#include // para SDL_CONTROLLER_BUTTON_B, SDL_CO... +#include // para SDL_SetHint, SDL_HINT_RENDER_DR... +#include // para SDL_SCANCODE_0, SDL_SCANCODE_DOWN +#include // para SDL_bool, Uint32 +#include // para SDL_GetTicks +#include // para system +#include // para errno, EEXIST, EACCES, ENAMETOO... +#include // para printf, perror +#include // para strcmp +#include // para mkdir, stat, S_IRWXU +#include // para getuid +#include // para exit, EXIT_FAILURE, rand, srand +#include // para basic_ostream, operator<<, cout +#include // para make_unique, unique_ptr +#include // para operator+, allocator, char_traits +#include "asset.h" // para Asset, AssetType +#include "dbgtxt.h" // para dbg_init +#include "game.h" // para Game, GAME_MODE_DEMO_OFF, GAME_... +#include "global_inputs.h" // para init +#include "hiscore_table.h" // para HiScoreTable +#include "input.h" // para Input, InputType +#include "instructions.h" // para Instructions +#include "intro.h" // para Intro +#include "jail_audio.h" // para JA_LoadMusic, JA_LoadSound, JA_... +#include "lang.h" // para Code, loadFromFile +#include "logo.h" // para Logo +#include "manage_hiscore_table.h" // para ManageHiScoreTable +#include "notifier.h" // para Notifier +#include "on_screen_help.h" // para OnScreenHelp +#include "options.h" // para options, loadOptionsFile, saveO... +#include "param.h" // para param, loadParamsFromFile #include "resource.h" //for Resource -#include "screen.h" // for Screen -#include "section.h" // for Name, name, Options, options -#include "title.h" // for Title -#include "utils.h" // for MusicFile, SoundFile, Options +#include "screen.h" // para Screen +#include "section.h" // para Name, name, Options, options +#include "title.h" // para Title +#include "utils.h" // para MusicFile, SoundFile, Options #ifndef _WIN32 -#include // for getpwuid, passwd +#include // para getpwuid, passwd #endif // Constructor @@ -770,4 +770,4 @@ void Director::shutdownSystem() #error "Sistema operativo no soportado" #endif } -#endif //ARCADE \ No newline at end of file +#endif // ARCADE \ No newline at end of file diff --git a/source/director.h b/source/director.h index ec6d5e8..01ef0f5 100644 --- a/source/director.h +++ b/source/director.h @@ -1,9 +1,9 @@ #pragma once -#include // for SDL_Renderer -#include // for SDL_Window -#include // for string -#include // for vector +#include // para SDL_Renderer +#include // para SDL_Window +#include // para string +#include // para vector namespace lang { enum class Code : int; @@ -23,8 +23,8 @@ private: std::streambuf *orig_buf; // Puntero al buffer de flujo original para restaurar std::cout // Variables - std::string executable_path_; // Path del ejecutable - std::string system_folder_; // Carpeta del sistema donde guardar datos + std::string executable_path_; // Path del ejecutable + std::string system_folder_; // Carpeta del sistema donde guardar datos // Inicializa jail_audio void initJailAudio(); diff --git a/source/enter_name.cpp b/source/enter_name.cpp index e9380fa..81f36ed 100644 --- a/source/enter_name.cpp +++ b/source/enter_name.cpp @@ -1,5 +1,5 @@ #include "enter_name.h" -#include // for max, min +#include // para max, min // Constructor EnterName::EnterName() diff --git a/source/explosions.cpp b/source/explosions.cpp index cdbb3db..b4fc259 100644 --- a/source/explosions.cpp +++ b/source/explosions.cpp @@ -1,6 +1,6 @@ #include "explosions.h" -#include // for move -#include "animated_sprite.h" // for SpriteAnimated +#include // para move +#include "animated_sprite.h" // para SpriteAnimated class Texture; // lines 3-3 // Constructor diff --git a/source/explosions.h b/source/explosions.h index 98ae8d3..1cb95b9 100644 --- a/source/explosions.h +++ b/source/explosions.h @@ -1,8 +1,8 @@ #pragma once -#include // for shared_ptr, unique_ptr -#include // for string -#include // for vector +#include // para shared_ptr, unique_ptr +#include // para string +#include // para vector class AnimatedSprite; class Texture; diff --git a/source/fade.cpp b/source/fade.cpp index 7fce218..775bbba 100644 --- a/source/fade.cpp +++ b/source/fade.cpp @@ -1,11 +1,11 @@ #include "fade.h" -#include // for SDL_BLENDMODE_BLEND, SDL_BLENDMODE_NONE -#include // for SDL_PIXELFORMAT_RGBA8888 -#include // for rand -#include // for min, max -#include "param.h" // for param +#include // para SDL_BLENDMODE_BLEND, SDL_BLENDMODE_NONE +#include // para SDL_PIXELFORMAT_RGBA8888 +#include // para rand +#include // para min, max +#include "param.h" // para param #include "screen.h" -#include "utils.h" // for Param, ParamGame, ParamFade +#include "utils.h" // para Param, ParamGame, ParamFade // Constructor Fade::Fade() diff --git a/source/fade.h b/source/fade.h index e52928e..156ea36 100644 --- a/source/fade.h +++ b/source/fade.h @@ -1,9 +1,9 @@ #pragma once -#include // for SDL_Rect -#include // for SDL_Renderer, SDL_Texture -#include // for Uint8, Uint16 -#include // for vector +#include // para SDL_Rect +#include // para SDL_Renderer, SDL_Texture +#include // para Uint8, Uint16 +#include // para vector // Tipos de fundido enum class FadeType : Uint8 diff --git a/source/game.cpp b/source/game.cpp index 292f183..217eb43 100644 --- a/source/game.cpp +++ b/source/game.cpp @@ -1,41 +1,41 @@ #include "game.h" -#include // for SDL_BLENDMODE_BLEND -#include // for SDL_PollEvent, SDL_Event, SDL_KEYDOWN -#include // for SDLK_1, SDLK_2, SDLK_3, SDLK_4 -#include // for SDL_PIXELFORMAT_RGBA8888 -#include // for SDL_RWFromFile, SDL_RWclose, SDL_R... -#include // for SDL_GetTicks -#include // for SDL_WINDOWEVENT_FOCUS_GAINED, SDL_... -#include // for rand -#include // for min, remove_if -#include // for basic_ostream, operator<<, basic_i... -#include // for cout -#include // for accumulate -#include // for move -#include "asset.h" // for Asset -#include "background.h" // for Background -#include "balloon.h" // for Balloon, BALLOON_SCORE_1, BALLOON_... -#include "balloon_formations.h" // for Stage, BalloonFormationParams, Bal... -#include "bullet.h" // for Bullet, BulletType, BulletMoveStatus -#include "explosions.h" // for Explosions -#include "fade.h" // for Fade, FadeType -#include "global_inputs.h" // for check -#include "input.h" // for InputType, Input, INPUT_DO_NOT_ALL... -#include "item.h" // for Item, ItemType::COFFEE_MACHINE, ItemType::CLOCK -#include "jail_audio.h" // for JA_PlaySound -#include "lang.h" // for getText -#include "manage_hiscore_table.h" // for ManageHiScoreTable -#include "notifier.h" // for Notifier -#include "options.h" // for options -#include "param.h" // for param -#include "player.h" // for Player, PlayerStatus -#include "resource.h" // for Resource -#include "scoreboard.h" // for Scoreboard, ScoreboardMode, SCOREB... -#include "screen.h" // for Screen -#include "section.h" // for Name, name, Options, options -#include "smart_sprite.h" // for SpriteSmart -#include "text.h" // for Text, TEXT_CENTER -#include "texture.h" // for Texture +#include // para SDL_BLENDMODE_BLEND +#include // para SDL_PollEvent, SDL_Event, SDL_KEYDOWN +#include // para SDLK_1, SDLK_2, SDLK_3, SDLK_4 +#include // para SDL_PIXELFORMAT_RGBA8888 +#include // para SDL_RWFromFile, SDL_RWclose, SDL_R... +#include // para SDL_GetTicks +#include // para SDL_WINDOWEVENT_FOCUS_GAINED, SDL_... +#include // para rand +#include // para min, remove_if +#include // para basic_ostream, operator<<, basic_i... +#include // para cout +#include // para accumulate +#include // para move +#include "asset.h" // para Asset +#include "background.h" // para Background +#include "balloon.h" // para Balloon, BALLOON_SCORE_1, BALLOON_... +#include "balloon_formations.h" // para Stage, BalloonFormationParams, Bal... +#include "bullet.h" // para Bullet, BulletType, BulletMoveStatus +#include "explosions.h" // para Explosions +#include "fade.h" // para Fade, FadeType +#include "global_inputs.h" // para check +#include "input.h" // para InputType, Input, INPUT_DO_NOT_ALL... +#include "item.h" // para Item, ItemType::COFFEE_MACHINE, ItemType::CLOCK +#include "jail_audio.h" // para JA_PlaySound +#include "lang.h" // para getText +#include "manage_hiscore_table.h" // para ManageHiScoreTable +#include "notifier.h" // para Notifier +#include "options.h" // para options +#include "param.h" // para param +#include "player.h" // para Player, PlayerStatus +#include "resource.h" // para Resource +#include "scoreboard.h" // para Scoreboard, ScoreboardMode, SCOREB... +#include "screen.h" // para Screen +#include "section.h" // para Name, name, Options, options +#include "smart_sprite.h" // para SpriteSmart +#include "text.h" // para Text, TEXT_CENTER +#include "texture.h" // para Texture struct JA_Music_t; // lines 35-35 struct JA_Sound_t; // lines 36-36 #include "dbgtxt.h" diff --git a/source/game.h b/source/game.h index f1e18df..76b5eb8 100644 --- a/source/game.h +++ b/source/game.h @@ -1,13 +1,13 @@ #pragma once -#include // for SDL_Renderer, SDL_Texture -#include // for Uint32 -#include // for shared_ptr, unique_ptr -#include // for string -#include // for vector -#include "balloon.h" // for Balloon -#include "player.h" // for Player -#include "utils.h" // for DemoKeys, Color, HiScoreEntry +#include // para SDL_Renderer, SDL_Texture +#include // para Uint32 +#include // para shared_ptr, unique_ptr +#include // para string +#include // para vector +#include "balloon.h" // para Balloon +#include "player.h" // para Player +#include "utils.h" // para DemoKeys, Color, HiScoreEntry class Asset; class Background; class BalloonFormations; diff --git a/source/game_logo.cpp b/source/game_logo.cpp index 503357a..bbc8101 100644 --- a/source/game_logo.cpp +++ b/source/game_logo.cpp @@ -1,16 +1,16 @@ #include "game_logo.h" -#include // for SDL_FLIP_HORIZONTAL -#include // for max -#include "animated_sprite.h" // for SpriteAnimated -#include "asset.h" // for Asset +#include // para SDL_FLIP_HORIZONTAL +#include // para max +#include "animated_sprite.h" // para SpriteAnimated +#include "asset.h" // para Asset #include "jail_audio.h" // JA_PlaySound -#include "param.h" // for param -#include "resource.h" // for Resource -#include "screen.h" // for Screen -#include "smart_sprite.h" // for SpriteSmart -#include "sprite.h" // for Sprite -#include "texture.h" // for Texture -#include "utils.h" // for Param, ParamGame, ParamTitle +#include "param.h" // para param +#include "resource.h" // para Resource +#include "screen.h" // para Screen +#include "smart_sprite.h" // para SpriteSmart +#include "sprite.h" // para Sprite +#include "texture.h" // para Texture +#include "utils.h" // para Param, ParamGame, ParamTitle // Constructor GameLogo::GameLogo(int x, int y) @@ -27,7 +27,6 @@ GameLogo::GameLogo(int x, int y) arcade_edition_sprite_(std::make_unique(arcade_edition_texture_, (param.game.width - arcade_edition_texture_->getWidth()) / 2, param.title.arcade_edition_position, arcade_edition_texture_->getWidth(), arcade_edition_texture_->getHeight())), - x_(x), y_(y) { diff --git a/source/game_logo.h b/source/game_logo.h index 2e6880f..a2fb8e0 100644 --- a/source/game_logo.h +++ b/source/game_logo.h @@ -1,6 +1,6 @@ #pragma once -#include // for unique_ptr, shared_ptr +#include // para unique_ptr, shared_ptr #include "animated_sprite.h" #include "smart_sprite.h" class Sprite; diff --git a/source/global_inputs.cpp b/source/global_inputs.cpp index e37a296..bd19a44 100644 --- a/source/global_inputs.cpp +++ b/source/global_inputs.cpp @@ -1,14 +1,14 @@ #include "global_inputs.h" -#include // for basic_string, operator+ -#include "input.h" // for Input, inputs_e, INPUT_DO_NOT_ALLOW_REPEAT -#include "jail_audio.h" // for JA_EnableMusic, JA_EnableSound -#include "lang.h" // for getText -#include "notifier.h" // for Notifier -#include "options.h" // for options +#include // para basic_string, operator+ +#include "input.h" // para Input, inputs_e, INPUT_DO_NOT_ALLOW_REPEAT +#include "jail_audio.h" // para JA_EnableMusic, JA_EnableSound +#include "lang.h" // para getText +#include "notifier.h" // para Notifier +#include "options.h" // para options #include "on_screen_help.h" -#include "screen.h" // for Screen -#include "section.h" // for SectionOptions, name, SectionName, options -#include "utils.h" // for OptionsAudio, Options, OptionsMusic, boolToOnOff +#include "screen.h" // para Screen +#include "section.h" // para SectionOptions, name, SectionName, options +#include "utils.h" // para OptionsAudio, Options, OptionsMusic, boolToOnOff namespace globalInputs { diff --git a/source/hiscore_table.cpp b/source/hiscore_table.cpp index 5a738b9..870abaf 100644 --- a/source/hiscore_table.cpp +++ b/source/hiscore_table.cpp @@ -1,25 +1,25 @@ #include "hiscore_table.h" -#include // for SDL_BLENDMODE_BLEND -#include // for SDL_PollEvent, SDL_Event, SDL_QUIT -#include // for SDL_PIXELFORMAT_RGBA8888 -#include // for SDL_GetTicks -#include // for SDL_WINDOWEVENT_SIZE_CHANGED -#include // for max -#include // for vector -#include "asset.h" // for Asset -#include "background.h" // for Background -#include "fade.h" // for Fade, FadeMode, FadeType -#include "global_inputs.h" // for check -#include "input.h" // for Input -#include "jail_audio.h" // for JA_GetMusicState, JA_Music_state -#include "lang.h" // for getText -#include "options.h" // for options -#include "param.h" // for param -#include "resource.h" // for Resource -#include "screen.h" // for Screen -#include "section.h" // for Name, name, Options, options -#include "text.h" // for Text, TEXT_CENTER, TEXT_SHADOW, TEXT... -#include "utils.h" // for Param, ParamGame, Color, HiScoreEntry +#include // para SDL_BLENDMODE_BLEND +#include // para SDL_PollEvent, SDL_Event, SDL_QUIT +#include // para SDL_PIXELFORMAT_RGBA8888 +#include // para SDL_GetTicks +#include // para SDL_WINDOWEVENT_SIZE_CHANGED +#include // para max +#include // para vector +#include "asset.h" // para Asset +#include "background.h" // para Background +#include "fade.h" // para Fade, FadeMode, FadeType +#include "global_inputs.h" // para check +#include "input.h" // para Input +#include "jail_audio.h" // para JA_GetMusicState, JA_Music_state +#include "lang.h" // para getText +#include "options.h" // para options +#include "param.h" // para param +#include "resource.h" // para Resource +#include "screen.h" // para Screen +#include "section.h" // para Name, name, Options, options +#include "text.h" // para Text, TEXT_CENTER, TEXT_SHADOW, TEXT... +#include "utils.h" // para Param, ParamGame, Color, HiScoreEntry // Constructor HiScoreTable::HiScoreTable() diff --git a/source/hiscore_table.h b/source/hiscore_table.h index 062e902..ebf97e5 100644 --- a/source/hiscore_table.h +++ b/source/hiscore_table.h @@ -1,10 +1,10 @@ #pragma once -#include // for SDL_Rect -#include // for SDL_Renderer, SDL_Texture -#include // for Uint16, Uint32, Uint8 -#include // for unique_ptr -#include // for string +#include // para SDL_Rect +#include // para SDL_Renderer, SDL_Texture +#include // para Uint16, Uint32, Uint8 +#include // para unique_ptr +#include // para string class Background; // lines 8-8 class Fade; // lines 9-9 class Text; // lines 10-10 diff --git a/source/input.cpp b/source/input.cpp index 06530ca..7863403 100644 --- a/source/input.cpp +++ b/source/input.cpp @@ -1,9 +1,9 @@ #include "input.h" -#include // for SDL_INIT_GAMECONTROLLER, SDL_InitSubS... -#include // for SDL_GetError -#include // for SDL_ENABLE -#include // for SDL_GetKeyboardState -#include // for basic_ostream, operator<<, cout, basi... +#include // para SDL_INIT_GAMECONTROLLER, SDL_InitSubS... +#include // para SDL_GetError +#include // para SDL_ENABLE +#include // para SDL_GetKeyboardState +#include // para basic_ostream, operator<<, cout, basi... // [SINGLETON] Hay que definir las variables estáticas, desde el .h sólo la hemos declarado Input *Input::input_ = nullptr; diff --git a/source/input.h b/source/input.h index 66d604e..7ab1a91 100644 --- a/source/input.h +++ b/source/input.h @@ -1,11 +1,11 @@ #pragma once -#include // for SDL_GameControllerButton, SDL_G... -#include // for SDL_Joystick -#include // for SDL_Scancode -#include // for Uint8 -#include // for string, basic_string -#include // for vector +#include // para SDL_GameControllerButton, SDL_G... +#include // para SDL_Joystick +#include // para SDL_Scancode +#include // para Uint8 +#include // para string, basic_string +#include // para vector /* connectedControllers es un vector donde estan todos los mandos encontrados [0 .. n] diff --git a/source/instructions.cpp b/source/instructions.cpp index 33cfc39..1e6fca9 100644 --- a/source/instructions.cpp +++ b/source/instructions.cpp @@ -1,26 +1,26 @@ #include "instructions.h" -#include // for SDL_BLENDMODE_BLEND -#include // for SDL_PollEvent, SDL_Event, SDL_QUIT -#include // for SDL_PIXELFORMAT_RGBA8888 -#include // for SDL_GetTicks -#include // for SDL_WINDOWEVENT_SIZE_CHANGED -#include // for max -#include // for move -#include "asset.h" // for Asset -#include "fade.h" // for Fade, FadeMode, FadeType -#include "global_inputs.h" // for check -#include "input.h" // for Input -#include "jail_audio.h" // for JA_GetMusicState, JA_Music_state -#include "lang.h" // for getText -#include "param.h" // for param -#include "resource.h" // for Resource -#include "screen.h" // for Screen -#include "section.h" // for Name, name, Options, options -#include "sprite.h" // for Sprite -#include "text.h" // for Text, TEXT_CENTER, TEXT_COLOR, TEXT_... -#include "texture.h" // for Texture -#include "tiled_bg.h" // for TiledBG, TILED_MODE_STATIC -#include "utils.h" // for Param, ParamGame, Color, shdw_txt_color +#include // para SDL_BLENDMODE_BLEND +#include // para SDL_PollEvent, SDL_Event, SDL_QUIT +#include // para SDL_PIXELFORMAT_RGBA8888 +#include // para SDL_GetTicks +#include // para SDL_WINDOWEVENT_SIZE_CHANGED +#include // para max +#include // para move +#include "asset.h" // para Asset +#include "fade.h" // para Fade, FadeMode, FadeType +#include "global_inputs.h" // para check +#include "input.h" // para Input +#include "jail_audio.h" // para JA_GetMusicState, JA_Music_state +#include "lang.h" // para getText +#include "param.h" // para param +#include "resource.h" // para Resource +#include "screen.h" // para Screen +#include "section.h" // para Name, name, Options, options +#include "sprite.h" // para Sprite +#include "text.h" // para Text, TEXT_CENTER, TEXT_COLOR, TEXT_... +#include "texture.h" // para Texture +#include "tiled_bg.h" // para TiledBG, TILED_MODE_STATIC +#include "utils.h" // para Param, ParamGame, Color, shdw_txt_color struct JA_Music_t; // lines 22-22 // Constructor diff --git a/source/instructions.h b/source/instructions.h index cf1d145..879fb77 100644 --- a/source/instructions.h +++ b/source/instructions.h @@ -1,10 +1,10 @@ #pragma once -#include // for SDL_Point, SDL_Rect -#include // for SDL_Texture, SDL_Renderer -#include // for Uint32 -#include // for unique_ptr, shared_ptr -#include // for vector +#include // para SDL_Point, SDL_Rect +#include // para SDL_Texture, SDL_Renderer +#include // para Uint32 +#include // para unique_ptr, shared_ptr +#include // para vector class Fade; class Sprite; class Text; @@ -33,7 +33,7 @@ private: SDL_Renderer *renderer_; // El renderizador de la ventana SDL_Texture *texture_; // Textura fija con el texto SDL_Texture *backbuffer_; // Textura para usar como backbuffer - + std::vector> item_textures_; // Vector con las texturas de los items std::vector> sprites_; // Vector con los sprites de los items std::unique_ptr text_; // Objeto para escribir texto diff --git a/source/intro.cpp b/source/intro.cpp index bb32210..5647137 100644 --- a/source/intro.cpp +++ b/source/intro.cpp @@ -1,22 +1,22 @@ #include "intro.h" -#include // for SDL_PollEvent, SDL_Event, SDL_QUIT, SDL... -#include // for SDL_GetTicks -#include // for SDL_WINDOWEVENT_SIZE_CHANGED -#include // for move -#include "asset.h" // for Asset -#include "global_inputs.h" // for check -#include "input.h" // for Input -#include "jail_audio.h" // for JA_StopMusic, JA_PlayMusic -#include "lang.h" // for getText -#include "param.h" // for param -#include "resource.h" // for Resource -#include "screen.h" // for Screen -#include "section.h" // for Name, name, Options, options -#include "smart_sprite.h" // for SpriteSmart -#include "text.h" // for Text -#include "texture.h" // for Texture -#include "utils.h" // for Param, ParamGame, Zone, BLOCK, Color -#include "writer.h" // for Writer +#include // para SDL_PollEvent, SDL_Event, SDL_QUIT, SDL... +#include // para SDL_GetTicks +#include // para SDL_WINDOWEVENT_SIZE_CHANGED +#include // para move +#include "asset.h" // para Asset +#include "global_inputs.h" // para check +#include "input.h" // para Input +#include "jail_audio.h" // para JA_StopMusic, JA_PlayMusic +#include "lang.h" // para getText +#include "param.h" // para param +#include "resource.h" // para Resource +#include "screen.h" // para Screen +#include "section.h" // para Name, name, Options, options +#include "smart_sprite.h" // para SpriteSmart +#include "text.h" // para Text +#include "texture.h" // para Texture +#include "utils.h" // para Param, ParamGame, Zone, BLOCK, Color +#include "writer.h" // para Writer struct JA_Music_t; // lines 19-19 // Constructor @@ -369,7 +369,7 @@ void Intro::updateScenes() void Intro::update() { constexpr int TICKS_SPEED = 15; - + if (SDL_GetTicks() - ticks_ > TICKS_SPEED) { // Actualiza el contador de ticks diff --git a/source/intro.h b/source/intro.h index 441b286..2ef57bc 100644 --- a/source/intro.h +++ b/source/intro.h @@ -1,10 +1,10 @@ #pragma once -#include // for Uint32, Uint8 -#include // for unique_ptr, shared_ptr -#include // for vector -#include "smart_sprite.h" // for SpriteSmart -#include "writer.h" // for Writer +#include // para Uint32, Uint8 +#include // para unique_ptr, shared_ptr +#include // para vector +#include "smart_sprite.h" // para SpriteSmart +#include "writer.h" // para Writer class Text; class Texture; struct JA_Music_t; // lines 11-11 diff --git a/source/item.cpp b/source/item.cpp index c35e8eb..7e6c7bb 100644 --- a/source/item.cpp +++ b/source/item.cpp @@ -1,7 +1,7 @@ #include "item.h" -#include // for rand -#include "animated_sprite.h" // for SpriteAnimated -#include "param.h" // for param +#include // para rand +#include "animated_sprite.h" // para SpriteAnimated +#include "param.h" // para param class Texture; // Constructor diff --git a/source/item.h b/source/item.h index c774dfc..8064c83 100644 --- a/source/item.h +++ b/source/item.h @@ -1,12 +1,12 @@ #pragma once -#include // for SDL_Rect -#include // for Uint16 -#include // for shared_ptr, unique_ptr -#include // for string -#include // for vector -#include "animated_sprite.h" // for SpriteAnimated -#include "utils.h" // for Circle +#include // para SDL_Rect +#include // para Uint16 +#include // para shared_ptr, unique_ptr +#include // para string +#include // para vector +#include "animated_sprite.h" // para SpriteAnimated +#include "utils.h" // para Circle class Texture; // Tipos de objetos diff --git a/source/jail_audio.cpp b/source/jail_audio.cpp index e5fc310..47af976 100644 --- a/source/jail_audio.cpp +++ b/source/jail_audio.cpp @@ -1,74 +1,91 @@ #ifndef JA_USESDLMIXER #include "jail_audio.h" -#include // for uint8_t -#include // for NULL, fseek, fclose, fopen, fread, ftell, FILE -#include // for free, malloc -#include "stb_vorbis.c" // for stb_vorbis_decode_memory +#include // para uint8_t +#include // para NULL, fseek, fclose, fopen, fread, ftell, FILE +#include // para free, malloc +#include "stb_vorbis.c" // para stb_vorbis_decode_memory #define JA_MAX_SIMULTANEOUS_CHANNELS 5 -struct JA_Sound_t { - Uint32 length {0}; - Uint8* buffer {NULL}; +struct JA_Sound_t +{ + Uint32 length{0}; + Uint8 *buffer{NULL}; }; -struct JA_Channel_t { - JA_Sound_t *sound; - int pos {0}; - int times {0}; - JA_Channel_state state { JA_CHANNEL_FREE }; +struct JA_Channel_t +{ + JA_Sound_t *sound; + int pos{0}; + int times{0}; + JA_Channel_state state{JA_CHANNEL_FREE}; }; -struct JA_Music_t { - int samples {0}; - int pos {0}; - int times {0}; - short* output {NULL}; - JA_Music_state state {JA_MUSIC_INVALID}; +struct JA_Music_t +{ + int samples{0}; + int pos{0}; + int times{0}; + short *output{NULL}; + JA_Music_state state{JA_MUSIC_INVALID}; }; -JA_Music_t *current_music{NULL}; -JA_Channel_t channels[JA_MAX_SIMULTANEOUS_CHANNELS]; +JA_Music_t *current_music{NULL}; +JA_Channel_t channels[JA_MAX_SIMULTANEOUS_CHANNELS]; -int JA_freq {48000}; -SDL_AudioFormat JA_format {AUDIO_S16}; -Uint8 JA_channels {2}; -int JA_musicVolume = 128; -int JA_soundVolume = 64; -bool JA_musicEnabled = true; -bool JA_soundEnabled = true; +int JA_freq{48000}; +SDL_AudioFormat JA_format{AUDIO_S16}; +Uint8 JA_channels{2}; +int JA_musicVolume = 128; +int JA_soundVolume = 64; +bool JA_musicEnabled = true; +bool JA_soundEnabled = true; SDL_AudioDeviceID sdlAudioDevice = 0; -void audioCallback(void * userdata, uint8_t * stream, int len) { +void audioCallback(void *userdata, uint8_t *stream, int len) +{ SDL_memset(stream, 0, len); - if (current_music != NULL && current_music->state == JA_MUSIC_PLAYING) { - const int size = SDL_min(len, current_music->samples*2-current_music->pos); - SDL_MixAudioFormat(stream, (Uint8*)(current_music->output+current_music->pos), AUDIO_S16, size, JA_musicVolume); - current_music->pos += size/2; - if (size < len) { - if (current_music->times != 0) { - SDL_MixAudioFormat(stream+size, (Uint8*)current_music->output, AUDIO_S16, len-size, JA_musicVolume); - current_music->pos = (len-size)/2; - if (current_music->times > 0) current_music->times--; - } else { + if (current_music != NULL && current_music->state == JA_MUSIC_PLAYING) + { + const int size = SDL_min(len, current_music->samples * 2 - current_music->pos); + SDL_MixAudioFormat(stream, (Uint8 *)(current_music->output + current_music->pos), AUDIO_S16, size, JA_musicVolume); + current_music->pos += size / 2; + if (size < len) + { + if (current_music->times != 0) + { + SDL_MixAudioFormat(stream + size, (Uint8 *)current_music->output, AUDIO_S16, len - size, JA_musicVolume); + current_music->pos = (len - size) / 2; + if (current_music->times > 0) + current_music->times--; + } + else + { current_music->pos = 0; current_music->state = JA_MUSIC_STOPPED; } } } // Mixar els channels mi amol - for (int i = 0; i < JA_MAX_SIMULTANEOUS_CHANNELS; i++) { - if (channels[i].state == JA_CHANNEL_PLAYING) { + for (int i = 0; i < JA_MAX_SIMULTANEOUS_CHANNELS; i++) + { + if (channels[i].state == JA_CHANNEL_PLAYING) + { const int size = SDL_min(len, channels[i].sound->length - channels[i].pos); SDL_MixAudioFormat(stream, channels[i].sound->buffer + channels[i].pos, AUDIO_S16, size, JA_soundVolume); channels[i].pos += size; - if (size < len) { - if (channels[i].times != 0) { - SDL_MixAudioFormat(stream + size, channels[i].sound->buffer, AUDIO_S16, len-size, JA_soundVolume); - channels[i].pos = len-size; - if (channels[i].times > 0) channels[i].times--; - } else { + if (size < len) + { + if (channels[i].times != 0) + { + SDL_MixAudioFormat(stream + size, channels[i].sound->buffer, AUDIO_S16, len - size, JA_soundVolume); + channels[i].pos = len - size; + if (channels[i].times > 0) + channels[i].times--; + } + else + { JA_StopChannel(i); } } @@ -76,23 +93,28 @@ void audioCallback(void * userdata, uint8_t * stream, int len) { } } -void JA_Init(const int freq, const SDL_AudioFormat format, const int channels) { +void JA_Init(const int freq, const SDL_AudioFormat format, const int channels) +{ JA_freq = freq; JA_format = format; JA_channels = channels; SDL_AudioSpec audioSpec{JA_freq, JA_format, JA_channels, 0, 1024, 0, 0, audioCallback, NULL}; - if (sdlAudioDevice != 0) SDL_CloseAudioDevice(sdlAudioDevice); + if (sdlAudioDevice != 0) + SDL_CloseAudioDevice(sdlAudioDevice); sdlAudioDevice = SDL_OpenAudioDevice(NULL, 0, &audioSpec, NULL, 0); SDL_PauseAudioDevice(sdlAudioDevice, 0); } -void JA_Quit() { +void JA_Quit() +{ SDL_PauseAudioDevice(sdlAudioDevice, 1); - if (sdlAudioDevice != 0) SDL_CloseAudioDevice(sdlAudioDevice); + if (sdlAudioDevice != 0) + SDL_CloseAudioDevice(sdlAudioDevice); sdlAudioDevice = 0; } -JA_Music_t *JA_LoadMusic(const char* filename) { +JA_Music_t *JA_LoadMusic(const char *filename) +{ int chan, samplerate; // [RZC 28/08/22] Carreguem primer el arxiu en memòria i després el descomprimim. Es algo més rapid. @@ -100,8 +122,9 @@ JA_Music_t *JA_LoadMusic(const char* filename) { fseek(f, 0, SEEK_END); long fsize = ftell(f); fseek(f, 0, SEEK_SET); - Uint8 *buffer = (Uint8*)malloc(fsize + 1); - if (fread(buffer, fsize, 1, f)!=1) return NULL; + Uint8 *buffer = (Uint8 *)malloc(fsize + 1); + if (fread(buffer, fsize, 1, f) != 1) + return NULL; fclose(f); JA_Music_t *music = new JA_Music_t(); @@ -109,17 +132,18 @@ JA_Music_t *JA_LoadMusic(const char* filename) { music->samples = stb_vorbis_decode_memory(buffer, fsize, &chan, &samplerate, &music->output); free(buffer); // [RZC 28/08/22] Abans el descomprimiem mentre el teniem obert -// music->samples = stb_vorbis_decode_filename(filename, &chan, &samplerate, &music->output); + // music->samples = stb_vorbis_decode_filename(filename, &chan, &samplerate, &music->output); SDL_AudioCVT cvt; SDL_BuildAudioCVT(&cvt, AUDIO_S16, chan, samplerate, JA_format, JA_channels, JA_freq); - if (cvt.needed) { + if (cvt.needed) + { cvt.len = music->samples * chan * 2; - cvt.buf = (Uint8 *) SDL_malloc(cvt.len * cvt.len_mult); + cvt.buf = (Uint8 *)SDL_malloc(cvt.len * cvt.len_mult); SDL_memcpy(cvt.buf, music->output, cvt.len); SDL_ConvertAudio(&cvt); free(music->output); - music->output = (short*)cvt.buf; + music->output = (short *)cvt.buf; } music->pos = 0; music->state = JA_MUSIC_STOPPED; @@ -129,9 +153,11 @@ JA_Music_t *JA_LoadMusic(const char* filename) { void JA_PlayMusic(JA_Music_t *music, const int loop) { - if (!JA_musicEnabled || !music) return; + if (!JA_musicEnabled || !music) + return; - if (current_music != NULL) { + if (current_music != NULL) + { current_music->pos = 0; current_music->state = JA_MUSIC_STOPPED; } @@ -143,67 +169,78 @@ void JA_PlayMusic(JA_Music_t *music, const int loop) void JA_PauseMusic() { - if (!JA_musicEnabled) return; + if (!JA_musicEnabled) + return; - if (current_music == NULL || current_music->state == JA_MUSIC_INVALID) return; + if (current_music == NULL || current_music->state == JA_MUSIC_INVALID) + return; current_music->state = JA_MUSIC_PAUSED; } void JA_ResumeMusic() { - if (!JA_musicEnabled) return; + if (!JA_musicEnabled) + return; - if (current_music == NULL || current_music->state == JA_MUSIC_INVALID) return; + if (current_music == NULL || current_music->state == JA_MUSIC_INVALID) + return; current_music->state = JA_MUSIC_PLAYING; } void JA_StopMusic() { - if (!JA_musicEnabled) return; + if (!JA_musicEnabled) + return; - if (current_music == NULL || current_music->state == JA_MUSIC_INVALID) return; + if (current_music == NULL || current_music->state == JA_MUSIC_INVALID) + return; current_music->pos = 0; current_music->state = JA_MUSIC_STOPPED; } -JA_Music_state JA_GetMusicState() { - if (!JA_musicEnabled) return JA_MUSIC_DISABLED; +JA_Music_state JA_GetMusicState() +{ + if (!JA_musicEnabled) + return JA_MUSIC_DISABLED; - if (current_music == NULL) return JA_MUSIC_INVALID; + if (current_music == NULL) + return JA_MUSIC_INVALID; return current_music->state; } -void JA_DeleteMusic(JA_Music_t *music) { - if (current_music == music) current_music = NULL; +void JA_DeleteMusic(JA_Music_t *music) +{ + if (current_music == music) + current_music = NULL; free(music->output); delete music; } int JA_SetMusicVolume(int volume) { - JA_musicVolume = volume > 128 ? 128 : volume < 0 ? 0 : volume; + JA_musicVolume = volume > 128 ? 128 : volume < 0 ? 0 + : volume; return JA_musicVolume; } void JA_EnableMusic(const bool value) { - if (!value && current_music != NULL && current_music->state==JA_MUSIC_PLAYING) JA_StopMusic(); + if (!value && current_music != NULL && current_music->state == JA_MUSIC_PLAYING) + JA_StopMusic(); JA_musicEnabled = value; } - - - - -JA_Sound_t *JA_NewSound(Uint8* buffer, Uint32 length) { +JA_Sound_t *JA_NewSound(Uint8 *buffer, Uint32 length) +{ JA_Sound_t *sound = new JA_Sound_t(); sound->buffer = buffer; sound->length = length; return sound; } -JA_Sound_t *JA_LoadSound(const char* filename) { +JA_Sound_t *JA_LoadSound(const char *filename) +{ JA_Sound_t *sound = new JA_Sound_t(); SDL_AudioSpec wavSpec; SDL_LoadWAV(filename, &wavSpec, &sound->buffer, &sound->length); @@ -211,7 +248,7 @@ JA_Sound_t *JA_LoadSound(const char* filename) { SDL_AudioCVT cvt; SDL_BuildAudioCVT(&cvt, wavSpec.format, wavSpec.channels, wavSpec.freq, JA_format, JA_channels, JA_freq); cvt.len = sound->length; - cvt.buf = (Uint8 *) SDL_malloc(cvt.len * cvt.len_mult); + cvt.buf = (Uint8 *)SDL_malloc(cvt.len * cvt.len_mult); SDL_memcpy(cvt.buf, sound->buffer, sound->length); SDL_ConvertAudio(&cvt); SDL_FreeWAV(sound->buffer); @@ -223,11 +260,16 @@ JA_Sound_t *JA_LoadSound(const char* filename) { int JA_PlaySound(JA_Sound_t *sound, const int loop) { - if (!JA_soundEnabled || !sound) return 0; + if (!JA_soundEnabled || !sound) + return 0; int channel = 0; - while (channel < JA_MAX_SIMULTANEOUS_CHANNELS && channels[channel].state != JA_CHANNEL_FREE) { channel++; } - if (channel == JA_MAX_SIMULTANEOUS_CHANNELS) channel = 0; + while (channel < JA_MAX_SIMULTANEOUS_CHANNELS && channels[channel].state != JA_CHANNEL_FREE) + { + channel++; + } + if (channel == JA_MAX_SIMULTANEOUS_CHANNELS) + channel = 0; channels[channel].sound = sound; channels[channel].times = loop; @@ -238,8 +280,10 @@ int JA_PlaySound(JA_Sound_t *sound, const int loop) void JA_DeleteSound(JA_Sound_t *sound) { - for (int i = 0; i < JA_MAX_SIMULTANEOUS_CHANNELS; i++) { - if (channels[i].sound == sound) JA_StopChannel(i); + for (int i = 0; i < JA_MAX_SIMULTANEOUS_CHANNELS; i++) + { + if (channels[i].sound == sound) + JA_StopChannel(i); } SDL_free(sound->buffer); delete sound; @@ -247,41 +291,60 @@ void JA_DeleteSound(JA_Sound_t *sound) void JA_PauseChannel(const int channel) { - if (!JA_soundEnabled) return; + if (!JA_soundEnabled) + return; - if (channel == -1) { - for (int i = 0; i < JA_MAX_SIMULTANEOUS_CHANNELS; i++) { - if (channels[i].state == JA_CHANNEL_PLAYING) channels[i].state = JA_CHANNEL_PAUSED; + if (channel == -1) + { + for (int i = 0; i < JA_MAX_SIMULTANEOUS_CHANNELS; i++) + { + if (channels[i].state == JA_CHANNEL_PLAYING) + channels[i].state = JA_CHANNEL_PAUSED; } - } else if (channel >= 0 && channel < JA_MAX_SIMULTANEOUS_CHANNELS) { - if (channels[channel].state == JA_CHANNEL_PLAYING) channels[channel].state = JA_CHANNEL_PAUSED; + } + else if (channel >= 0 && channel < JA_MAX_SIMULTANEOUS_CHANNELS) + { + if (channels[channel].state == JA_CHANNEL_PLAYING) + channels[channel].state = JA_CHANNEL_PAUSED; } } void JA_ResumeChannel(const int channel) { - if (!JA_soundEnabled) return; + if (!JA_soundEnabled) + return; - if (channel == -1) { - for (int i = 0; i < JA_MAX_SIMULTANEOUS_CHANNELS; i++) { - if (channels[i].state == JA_CHANNEL_PAUSED) channels[i].state = JA_CHANNEL_PLAYING; + if (channel == -1) + { + for (int i = 0; i < JA_MAX_SIMULTANEOUS_CHANNELS; i++) + { + if (channels[i].state == JA_CHANNEL_PAUSED) + channels[i].state = JA_CHANNEL_PLAYING; } - } else if (channel >= 0 && channel < JA_MAX_SIMULTANEOUS_CHANNELS) { - if (channels[channel].state == JA_CHANNEL_PAUSED) channels[channel].state = JA_CHANNEL_PLAYING; + } + else if (channel >= 0 && channel < JA_MAX_SIMULTANEOUS_CHANNELS) + { + if (channels[channel].state == JA_CHANNEL_PAUSED) + channels[channel].state = JA_CHANNEL_PLAYING; } } void JA_StopChannel(const int channel) { - if (!JA_soundEnabled) return; + if (!JA_soundEnabled) + return; - if (channel == -1) { - for (int i = 0; i < JA_MAX_SIMULTANEOUS_CHANNELS; i++) { + if (channel == -1) + { + for (int i = 0; i < JA_MAX_SIMULTANEOUS_CHANNELS; i++) + { channels[i].state = JA_CHANNEL_FREE; channels[i].pos = 0; channels[i].sound = NULL; } - } else if (channel >= 0 && channel < JA_MAX_SIMULTANEOUS_CHANNELS) { + } + else if (channel >= 0 && channel < JA_MAX_SIMULTANEOUS_CHANNELS) + { channels[channel].state = JA_CHANNEL_FREE; channels[channel].pos = 0; channels[channel].sound = NULL; @@ -290,15 +353,18 @@ void JA_StopChannel(const int channel) JA_Channel_state JA_GetChannelState(const int channel) { - if (!JA_soundEnabled) return JA_SOUND_DISABLED; + if (!JA_soundEnabled) + return JA_SOUND_DISABLED; - if (channel < 0 || channel >= JA_MAX_SIMULTANEOUS_CHANNELS) return JA_CHANNEL_INVALID; + if (channel < 0 || channel >= JA_MAX_SIMULTANEOUS_CHANNELS) + return JA_CHANNEL_INVALID; return channels[channel].state; } int JA_SetSoundVolume(int volume) { - JA_soundVolume = volume > 128 ? 128 : volume < 0 ? 0 : volume; + JA_soundVolume = volume > 128 ? 128 : volume < 0 ? 0 + : volume; return JA_soundVolume; } @@ -306,15 +372,17 @@ void JA_EnableSound(const bool value) { for (int i = 0; i < JA_MAX_SIMULTANEOUS_CHANNELS; i++) { - if (channels[i].state == JA_CHANNEL_PLAYING) JA_StopChannel(i); + if (channels[i].state == JA_CHANNEL_PLAYING) + JA_StopChannel(i); } JA_soundEnabled = value; } int JA_SetVolume(int volume) { - JA_musicVolume = volume > 128 ? 128 : volume < 0 ? 0 : volume; - JA_soundVolume = JA_musicVolume/2; + JA_musicVolume = volume > 128 ? 128 : volume < 0 ? 0 + : volume; + JA_soundVolume = JA_musicVolume / 2; return JA_musicVolume; } diff --git a/source/jail_audio.h b/source/jail_audio.h index 6407eed..6f96f50 100644 --- a/source/jail_audio.h +++ b/source/jail_audio.h @@ -1,17 +1,31 @@ #pragma once -#include // for SDL_AudioFormat -#include // for Uint32, Uint8 -struct JA_Music_t; // lines 5-5 -struct JA_Sound_t; // lines 6-6 +#include // para SDL_AudioFormat +#include // para Uint32, Uint8 +struct JA_Music_t; // lines 5-5 +struct JA_Sound_t; // lines 6-6 -enum JA_Channel_state { JA_CHANNEL_INVALID, JA_CHANNEL_FREE, JA_CHANNEL_PLAYING, JA_CHANNEL_PAUSED, JA_SOUND_DISABLED }; -enum JA_Music_state { JA_MUSIC_INVALID, JA_MUSIC_PLAYING, JA_MUSIC_PAUSED, JA_MUSIC_STOPPED, JA_MUSIC_DISABLED }; +enum JA_Channel_state +{ + JA_CHANNEL_INVALID, + JA_CHANNEL_FREE, + JA_CHANNEL_PLAYING, + JA_CHANNEL_PAUSED, + JA_SOUND_DISABLED +}; +enum JA_Music_state +{ + JA_MUSIC_INVALID, + JA_MUSIC_PLAYING, + JA_MUSIC_PAUSED, + JA_MUSIC_STOPPED, + JA_MUSIC_DISABLED +}; void JA_Init(const int freq, const SDL_AudioFormat format, const int channels); void JA_Quit(); -JA_Music_t *JA_LoadMusic(const char* filename); +JA_Music_t *JA_LoadMusic(const char *filename); void JA_PlayMusic(JA_Music_t *music, const int loop = -1); void JA_PauseMusic(); void JA_ResumeMusic(); @@ -21,8 +35,8 @@ void JA_DeleteMusic(JA_Music_t *music); int JA_SetMusicVolume(int volume); void JA_EnableMusic(const bool value); -JA_Sound_t *JA_NewSound(Uint8* buffer, Uint32 length); -JA_Sound_t *JA_LoadSound(const char* filename); +JA_Sound_t *JA_NewSound(Uint8 *buffer, Uint32 length); +JA_Sound_t *JA_LoadSound(const char *filename); int JA_PlaySound(JA_Sound_t *sound, const int loop = 0); void JA_PauseChannel(const int channel); void JA_ResumeChannel(const int channel); diff --git a/source/jail_shader.cpp b/source/jail_shader.cpp index 27044ee..44d75d3 100644 --- a/source/jail_shader.cpp +++ b/source/jail_shader.cpp @@ -1,10 +1,10 @@ #ifndef NO_SHADERS #include "jail_shader.h" -#include // for SDL_Point -#include // for NULL, free, malloc, exit -#include // for strncmp -#include // for basic_ostream, char_traits, operator<< +#include // para SDL_Point +#include // para NULL, free, malloc, exit +#include // para strncmp +#include // para basic_ostream, char_traits, operator<< #ifdef __APPLE__ #include "CoreFoundation/CoreFoundation.h" @@ -14,7 +14,7 @@ #include #else #include -#endif //!ESSENTIAL_GL_PRACTICES_SUPPORT_GL3 +#endif //! ESSENTIAL_GL_PRACTICES_SUPPORT_GL3 #else #include #endif @@ -24,14 +24,14 @@ namespace shader SDL_Window *win = nullptr; SDL_Renderer *renderer = nullptr; GLuint programId = 0; - SDL_Texture* backBuffer = nullptr; - SDL_Point win_size = {320*4, 256*4}; + SDL_Texture *backBuffer = nullptr; + SDL_Point win_size = {320 * 4, 256 * 4}; SDL_Point tex_size = {320, 256}; bool usingOpenGL; - #ifndef __APPLE__ +#ifndef __APPLE__ - // I'm avoiding the use of GLEW or some extensions handler, but that + // I'm avoiding the use of GLEW or some extensions handler, but that // doesn't mean you should... PFNGLCREATESHADERPROC glCreateShader; PFNGLSHADERSOURCEPROC glShaderSource; @@ -47,7 +47,8 @@ namespace shader PFNGLGETPROGRAMINFOLOGPROC glGetProgramInfoLog; PFNGLUSEPROGRAMPROC glUseProgram; - bool initGLExtensions() { + bool initGLExtensions() + { glCreateShader = (PFNGLCREATESHADERPROC)SDL_GL_GetProcAddress("glCreateShader"); glShaderSource = (PFNGLSHADERSOURCEPROC)SDL_GL_GetProcAddress("glShaderSource"); glCompileShader = (PFNGLCOMPILESHADERPROC)SDL_GL_GetProcAddress("glCompileShader"); @@ -62,56 +63,60 @@ namespace shader glGetProgramInfoLog = (PFNGLGETPROGRAMINFOLOGPROC)SDL_GL_GetProcAddress("glGetProgramInfoLog"); glUseProgram = (PFNGLUSEPROGRAMPROC)SDL_GL_GetProcAddress("glUseProgram"); - return glCreateShader && glShaderSource && glCompileShader && glGetShaderiv && - glGetShaderInfoLog && glDeleteShader && glAttachShader && glCreateProgram && - glLinkProgram && glValidateProgram && glGetProgramiv && glGetProgramInfoLog && - glUseProgram; + return glCreateShader && glShaderSource && glCompileShader && glGetShaderiv && + glGetShaderInfoLog && glDeleteShader && glAttachShader && glCreateProgram && + glLinkProgram && glValidateProgram && glGetProgramiv && glGetProgramInfoLog && + glUseProgram; } - #endif +#endif - GLuint compileShader(const char* source, GLuint shaderType) { + GLuint compileShader(const char *source, GLuint shaderType) + { // Create ID for shader GLuint result = glCreateShader(shaderType); // Add define depending on shader type - const char *sources[2] = { shaderType==GL_VERTEX_SHADER?"#define VERTEX\n":"#define FRAGMENT\n", source }; + const char *sources[2] = {shaderType == GL_VERTEX_SHADER ? "#define VERTEX\n" : "#define FRAGMENT\n", source}; // Define shader text glShaderSource(result, 2, sources, NULL); // Compile shader glCompileShader(result); - //Check vertex shader for errors + // Check vertex shader for errors GLint shaderCompiled = GL_FALSE; - glGetShaderiv( result, GL_COMPILE_STATUS, &shaderCompiled ); - if( shaderCompiled != GL_TRUE ) { + glGetShaderiv(result, GL_COMPILE_STATUS, &shaderCompiled); + if (shaderCompiled != GL_TRUE) + { std::cout << "Error en la compilación: " << result << "!" << std::endl; GLint logLength; glGetShaderiv(result, GL_INFO_LOG_LENGTH, &logLength); if (logLength > 0) { - GLchar *log = (GLchar*)malloc(logLength); + GLchar *log = (GLchar *)malloc(logLength); glGetShaderInfoLog(result, logLength, &logLength, log); std::cout << "Shader compile log:" << log << std::endl; free(log); } glDeleteShader(result); result = 0; -// } else { -// std::cout << "Shader compilado correctamente. Id = " << result << std::endl; + // } else { + // std::cout << "Shader compilado correctamente. Id = " << result << std::endl; } return result; } - GLuint compileProgram(const char* vertexShaderSource, const char* fragmentShaderSource) { + GLuint compileProgram(const char *vertexShaderSource, const char *fragmentShaderSource) + { GLuint programId = 0; GLuint vtxShaderId, fragShaderId; programId = glCreateProgram(); vtxShaderId = compileShader(vertexShaderSource, GL_VERTEX_SHADER); - fragShaderId = compileShader(fragmentShaderSource?fragmentShaderSource:vertexShaderSource, GL_FRAGMENT_SHADER); + fragShaderId = compileShader(fragmentShaderSource ? fragmentShaderSource : vertexShaderSource, GL_FRAGMENT_SHADER); - if(vtxShaderId && fragShaderId) { + if (vtxShaderId && fragShaderId) + { // Associate shader with program glAttachShader(programId, vtxShaderId); glAttachShader(programId, fragShaderId); @@ -121,24 +126,28 @@ namespace shader // Check the status of the compile/link GLint logLen; glGetProgramiv(programId, GL_INFO_LOG_LENGTH, &logLen); - if(logLen > 0) { - char* log = (char*) malloc(logLen * sizeof(char)); + if (logLen > 0) + { + char *log = (char *)malloc(logLen * sizeof(char)); // Show any errors as appropriate glGetProgramInfoLog(programId, logLen, &logLen, log); - std::cout << "Prog Info Log: " << std::endl << log << std::endl; + std::cout << "Prog Info Log: " << std::endl + << log << std::endl; free(log); } } - if(vtxShaderId) { + if (vtxShaderId) + { glDeleteShader(vtxShaderId); } - if(fragShaderId) { + if (fragShaderId) + { glDeleteShader(fragShaderId); } return programId; } - const bool init(SDL_Window* win, SDL_Texture* backBuffer, const char* vertexShader, const char* fragmentShader) + const bool init(SDL_Window *win, SDL_Texture *backBuffer, const char *vertexShader, const char *fragmentShader) { shader::win = win; shader::renderer = SDL_GetRenderer(win); @@ -155,19 +164,23 @@ namespace shader SDL_RendererInfo rendererInfo; SDL_GetRendererInfo(renderer, &rendererInfo); - if(!strncmp(rendererInfo.name, "opengl", 6)) { - //std::cout << "Es OpenGL!" << std::endl; - #ifndef __APPLE__ - if (!initGLExtensions()) { + if (!strncmp(rendererInfo.name, "opengl", 6)) + { + // std::cout << "Es OpenGL!" << std::endl; +#ifndef __APPLE__ + if (!initGLExtensions()) + { std::cout << "WARNING: No s'han pogut inicialitzar les extensions d'OpenGL!" << std::endl; usingOpenGL = false; return false; } - #endif +#endif // Compilar el shader y dejarlo listo para usar. programId = compileProgram(vertexShader, fragmentShader); - //std::cout << "programId = " << programId << std::endl; - } else { + // std::cout << "programId = " << programId << std::endl; + } + else + { std::cout << "WARNING: El driver del renderer no es OpenGL." << std::endl; usingOpenGL = false; return false; @@ -180,19 +193,21 @@ namespace shader { GLint oldProgramId; // Guarrada para obtener el textureid (en driverdata->texture) - //Detach the texture + // Detach the texture SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255); SDL_SetRenderTarget(renderer, NULL); SDL_RenderClear(renderer); - if (usingOpenGL) { + if (usingOpenGL) + { SDL_GL_BindTexture(backBuffer, NULL, NULL); - if(programId != 0) { - glGetIntegerv(GL_CURRENT_PROGRAM,&oldProgramId); + if (programId != 0) + { + glGetIntegerv(GL_CURRENT_PROGRAM, &oldProgramId); glUseProgram(programId); } - + GLfloat minx, miny, maxx, maxy; GLfloat minu, maxu, minv, maxv; @@ -210,21 +225,24 @@ namespace shader glViewport(0, 0, win_size.x, win_size.y); glBegin(GL_TRIANGLE_STRIP); - glTexCoord2f(minu, minv); - glVertex2f(minx, miny); - glTexCoord2f(maxu, minv); - glVertex2f(maxx, miny); - glTexCoord2f(minu, maxv); - glVertex2f(minx, maxy); - glTexCoord2f(maxu, maxv); - glVertex2f(maxx, maxy); + glTexCoord2f(minu, minv); + glVertex2f(minx, miny); + glTexCoord2f(maxu, minv); + glVertex2f(maxx, miny); + glTexCoord2f(minu, maxv); + glVertex2f(minx, maxy); + glTexCoord2f(maxu, maxv); + glVertex2f(maxx, maxy); glEnd(); SDL_GL_SwapWindow(win); - if(programId != 0) { + if (programId != 0) + { glUseProgram(oldProgramId); } - } else { + } + else + { SDL_RenderCopy(renderer, backBuffer, NULL, NULL); SDL_RenderPresent(renderer); } diff --git a/source/jail_shader.h b/source/jail_shader.h index 4286871..5c113ad 100644 --- a/source/jail_shader.h +++ b/source/jail_shader.h @@ -2,8 +2,8 @@ #pragma once -#include // for SDL_Texture -#include // for SDL_Window +#include // para SDL_Texture +#include // para SDL_Window // TIPS: // ======================================================================= @@ -27,7 +27,7 @@ // Els shaders li'ls passem com una cadena, som nosaltres els que s'encarreguem // de carregarlos de disc, amb fopen, ifstream, jfile o el que vullgues. // Si els tens en un std::string, passa-li-la com "cadena.c_str()". -// +// // Poden ser els dos el mateix arxiu, com fa libRetro, jo desde dins ja fique // els defines necessaris. Si es el mateix arxiu, pots no ficar el quart paràmetre. // @@ -40,8 +40,8 @@ namespace shader { - const bool init(SDL_Window* win, SDL_Texture* backBuffer, - const char* vertexShader, const char* fragmentShader=nullptr); + const bool init(SDL_Window *win, SDL_Texture *backBuffer, + const char *vertexShader, const char *fragmentShader = nullptr); void render(); } diff --git a/source/lang.cpp b/source/lang.cpp index 0724edd..7348488 100644 --- a/source/lang.cpp +++ b/source/lang.cpp @@ -1,11 +1,11 @@ #include "lang.h" -#include // for basic_ifstream, basic_istream, ifstream -#include // for vector +#include // para basic_ifstream, basic_istream, ifstream +#include // para vector namespace lang -{ +{ std::vector texts; // Vector con los textos - + // Inicializa los textos del juego en el idioma seleccionado bool loadFromFile(std::string file_path) { diff --git a/source/lang.h b/source/lang.h index 441328a..9cc414e 100644 --- a/source/lang.h +++ b/source/lang.h @@ -1,6 +1,6 @@ #pragma once -#include // for string +#include // para string namespace lang { diff --git a/source/logo.cpp b/source/logo.cpp index a8237f9..844dbad 100644 --- a/source/logo.cpp +++ b/source/logo.cpp @@ -1,19 +1,19 @@ #include "logo.h" -#include // for SDL_PollEvent, SDL_Event, SDL_QUIT, SDL... -#include // for SDL_Renderer -#include // for SDL_GetTicks -#include // for SDL_WINDOWEVENT_SIZE_CHANGED -#include // for move -#include "asset.h" // for Asset -#include "global_inputs.h" // for check -#include "input.h" // for Input -#include "jail_audio.h" // for JA_StopMusic -#include "param.h" // for param -#include "resource.h" // for Resource -#include "screen.h" // for Screen -#include "section.h" // for Name, name, Options, options -#include "sprite.h" // for Sprite -#include "texture.h" // for Texture +#include // para SDL_PollEvent, SDL_Event, SDL_QUIT, SDL... +#include // para SDL_Renderer +#include // para SDL_GetTicks +#include // para SDL_WINDOWEVENT_SIZE_CHANGED +#include // para move +#include "asset.h" // para Asset +#include "global_inputs.h" // para check +#include "input.h" // para Input +#include "jail_audio.h" // para JA_StopMusic +#include "param.h" // para param +#include "resource.h" // para Resource +#include "screen.h" // para Screen +#include "section.h" // para Name, name, Options, options +#include "sprite.h" // para Sprite +#include "texture.h" // para Texture // Constructor Logo::Logo() diff --git a/source/logo.h b/source/logo.h index 2cc5611..a3e1d09 100644 --- a/source/logo.h +++ b/source/logo.h @@ -1,11 +1,11 @@ #pragma once -#include // for SDL_Point -#include // for Uint32 -#include // for unique_ptr, shared_ptr -#include // for vector -#include "sprite.h" // for Sprite -#include "utils.h" // for Color +#include // para SDL_Point +#include // para Uint32 +#include // para unique_ptr, shared_ptr +#include // para vector +#include "sprite.h" // para Sprite +#include "utils.h" // para Color class Texture; /* @@ -26,7 +26,7 @@ private: static constexpr int END_LOGO_COUNTER_MARK = 400; // Tiempo del contador para terminar el logo static constexpr int POST_LOGO_DURATION = 20; // Tiempo que dura el logo con el fade al maximo static constexpr int SPEED = 8; // Velocidad de desplazamiento de cada linea - + // Objetos y punteros std::shared_ptr since_texture_; // Textura con los graficos "Since 1998" std::unique_ptr since_sprite_; // Sprite para manejar la sinceTexture diff --git a/source/main.cpp b/source/main.cpp index f7f4fc1..6f4041d 100644 --- a/source/main.cpp +++ b/source/main.cpp @@ -7,9 +7,9 @@ Actualizando a la versión "Arcade Edition" en 08/05/2024 */ -#include // for char_traits, basic_ostream, operator<<, cout -#include // for make_unique, unique_ptr -#include "director.h" // for Director +#include // para char_traits, basic_ostream, operator<<, cout +#include // para make_unique, unique_ptr +#include "director.h" // para Director int main(int argc, char *argv[]) { diff --git a/source/manage_hiscore_table.cpp b/source/manage_hiscore_table.cpp index 910bf85..f20dfe7 100644 --- a/source/manage_hiscore_table.cpp +++ b/source/manage_hiscore_table.cpp @@ -1,10 +1,10 @@ #include "manage_hiscore_table.h" -#include // for SDL_GetError -#include // for SDL_RWread, SDL_RWwrite, SDL_RWFromFile -#include // for free, malloc -#include // for sort -#include // for basic_ostream, char_traits, operator<< -#include "utils.h" // for HiScoreEntry +#include // para SDL_GetError +#include // para SDL_RWread, SDL_RWwrite, SDL_RWFromFile +#include // para free, malloc +#include // para sort +#include // para basic_ostream, char_traits, operator<< +#include "utils.h" // para HiScoreEntry // Resetea la tabla a los valores por defecto void ManageHiScoreTable::clear() diff --git a/source/manage_hiscore_table.h b/source/manage_hiscore_table.h index 2543a6f..0820aa8 100644 --- a/source/manage_hiscore_table.h +++ b/source/manage_hiscore_table.h @@ -1,7 +1,7 @@ #pragma once -#include // for string -#include // for vector +#include // para string +#include // para vector struct HiScoreEntry; /* diff --git a/source/moving_sprite.cpp b/source/moving_sprite.cpp index 6f0a51c..2ad08c9 100644 --- a/source/moving_sprite.cpp +++ b/source/moving_sprite.cpp @@ -1,5 +1,5 @@ #include "moving_sprite.h" -#include "texture.h" // for Texture +#include "texture.h" // para Texture // Constructor MovingSprite::MovingSprite(std::shared_ptr texture, SDL_Rect pos, Rotate rotate, float zoom_w, float zoom_h, SDL_RendererFlip flip) diff --git a/source/moving_sprite.h b/source/moving_sprite.h index 788b0ba..e73a5dc 100644 --- a/source/moving_sprite.h +++ b/source/moving_sprite.h @@ -1,10 +1,10 @@ #pragma once -#include // for SDL_Rect, SDL_Point -#include // for SDL_RendererFlip -#include // for Uint16 -#include // for shared_ptr -#include "sprite.h" // for Sprite +#include // para SDL_Rect, SDL_Point +#include // para SDL_RendererFlip +#include // para Uint16 +#include // para shared_ptr +#include "sprite.h" // para Sprite class Texture; // Clase MovingSprite. Añade movimiento y efectos de rotación, zoom y flip al sprite diff --git a/source/notifier.cpp b/source/notifier.cpp index 9a01dc4..5baa3e3 100644 --- a/source/notifier.cpp +++ b/source/notifier.cpp @@ -1,14 +1,14 @@ #include "notifier.h" -#include // for SDL_BLENDMODE_BLEND -#include // for SDL_PIXELFORMAT_RGBA8888 -#include // for string -#include "jail_audio.h" // for JA_DeleteSound, JA_LoadSound, JA_Pla... -#include "param.h" // for param -#include "resource.h" // for Resource -#include "screen.h" // for Screen -#include "sprite.h" // for Sprite -#include "text.h" // for Text -#include "texture.h" // for Texture +#include // para SDL_BLENDMODE_BLEND +#include // para SDL_PIXELFORMAT_RGBA8888 +#include // para string +#include "jail_audio.h" // para JA_DeleteSound, JA_LoadSound, JA_Pla... +#include "param.h" // para param +#include "resource.h" // para Resource +#include "screen.h" // para Screen +#include "sprite.h" // para Sprite +#include "text.h" // para Text +#include "texture.h" // para Texture // [SINGLETON] Hay que definir las variables estáticas, desde el .h sólo la hemos declarado Notifier *Notifier::notifier_ = nullptr; diff --git a/source/notifier.h b/source/notifier.h index 1c7befd..c2daaa0 100644 --- a/source/notifier.h +++ b/source/notifier.h @@ -1,11 +1,11 @@ #pragma once -#include // for SDL_Rect -#include // for SDL_Renderer -#include // for shared_ptr, unique_ptr -#include // for string, basic_string -#include // for vector -#include "utils.h" // for Color +#include // para SDL_Rect +#include // para SDL_Renderer +#include // para shared_ptr, unique_ptr +#include // para string, basic_string +#include // para vector +#include "utils.h" // para Color class Sprite; class Text; class Texture; @@ -57,6 +57,9 @@ private: int y; int travel_dist; std::string code; // Permite asignar un código a la notificación + + // Constructor vacío + Notification() = default; }; // Objetos y punteros diff --git a/source/on_screen_help.cpp b/source/on_screen_help.cpp index c7cca75..a8f79df 100644 --- a/source/on_screen_help.cpp +++ b/source/on_screen_help.cpp @@ -1,16 +1,16 @@ #include "on_screen_help.h" -#include // for SDL_BLENDMODE_BLEND -#include // for SDL_PIXELFORMAT_RGBA8888 -#include // for make_unique, make_shared, unique_ptr -#include "asset.h" // for Asset -#include "lang.h" // for getText -#include "param.h" // for param -#include "resource.h" // for Resource -#include "screen.h" // for Screen -#include "sprite.h" // for Sprite -#include "text.h" // for Text -#include "texture.h" // for Texture -#include "utils.h" // for easeInOutSine, Param, ParamGame +#include // para SDL_BLENDMODE_BLEND +#include // para SDL_PIXELFORMAT_RGBA8888 +#include // para make_unique, make_shared, unique_ptr +#include "asset.h" // para Asset +#include "lang.h" // para getText +#include "param.h" // para param +#include "resource.h" // para Resource +#include "screen.h" // para Screen +#include "sprite.h" // para Sprite +#include "text.h" // para Text +#include "texture.h" // para Texture +#include "utils.h" // para easeInOutSine, Param, ParamGame // [SINGLETON] Hay que definir las variables estáticas, desde el .h sólo la hemos declarado OnScreenHelp *OnScreenHelp::onScreenHelp = nullptr; diff --git a/source/on_screen_help.h b/source/on_screen_help.h index 90b5a3e..df27325 100644 --- a/source/on_screen_help.h +++ b/source/on_screen_help.h @@ -1,8 +1,8 @@ #pragma once -#include // for SDL_Rect -#include // for SDL_Texture -#include // for vector +#include // para SDL_Rect +#include // para SDL_Texture +#include // para vector class Sprite; class Text; diff --git a/source/options.cpp b/source/options.cpp index d5026a2..2b5b76d 100644 --- a/source/options.cpp +++ b/source/options.cpp @@ -1,13 +1,13 @@ #include "options.h" -#include // for SDL_GameControllerButton, SDL_C... -#include // for max, min -#include // for basic_ostream, operator<<, basi... -#include // for cout -#include // for vector -#include "input.h" // for inputs_e, INPUT_USE_ANY, INPUT_... -#include "lang.h" // for lang_e -#include "screen.h" // for ScreenVideoMode, ScreenFilter -#include "utils.h" // for OptionsController, Options, op_... +#include // para SDL_GameControllerButton, SDL_C... +#include // para max, min +#include // para basic_ostream, operator<<, basi... +#include // para cout +#include // para vector +#include "input.h" // para inputs_e, INPUT_USE_ANY, INPUT_... +#include "lang.h" // para lang_e +#include "screen.h" // para ScreenVideoMode, ScreenFilter +#include "utils.h" // para OptionsController, Options, op_... // Variables Options options; diff --git a/source/options.h b/source/options.h index 2987999..474b289 100644 --- a/source/options.h +++ b/source/options.h @@ -1,6 +1,6 @@ #pragma once -#include // for string +#include // para string struct Options; // Variables diff --git a/source/param.cpp b/source/param.cpp index 8e0fbd0..5088156 100644 --- a/source/param.cpp +++ b/source/param.cpp @@ -1,10 +1,10 @@ #include "param.h" -#include // for char_traits, basic_ostream, basic_ifstream, basi... -#include // for cout +#include // para char_traits, basic_ostream, basic_ifstream, basi... +#include // para cout #include #include #include -#include "utils.h" // for Param, ParamGame, Zone, ParamBalloon +#include "utils.h" // para Param, ParamGame, Zone, ParamBalloon Param param; diff --git a/source/param.h b/source/param.h index 8e688a5..2569c44 100644 --- a/source/param.h +++ b/source/param.h @@ -1,6 +1,6 @@ #pragma once -#include // for string +#include // para string struct Param; extern Param param; diff --git a/source/player.cpp b/source/player.cpp index b274eeb..e3d611a 100644 --- a/source/player.cpp +++ b/source/player.cpp @@ -1,13 +1,13 @@ #include "player.h" -#include // for SDL_FLIP_HORIZONTAL, SDL_FLIP_NONE, SDL... -#include // for SDL_GetTicks -#include // for rand -#include // for max, min -#include "animated_sprite.h" // for SpriteAnimated -#include "input.h" // for inputs_e -#include "param.h" // for param -#include "texture.h" // for Texture -#include "scoreboard.h" // for Texture +#include // para SDL_FLIP_HORIZONTAL, SDL_FLIP_NONE, SDL... +#include // para SDL_GetTicks +#include // para rand +#include // para max, min +#include "animated_sprite.h" // para SpriteAnimated +#include "input.h" // para inputs_e +#include "param.h" // para param +#include "texture.h" // para Texture +#include "scoreboard.h" // para Texture #include "options.h" // Constructor diff --git a/source/player.h b/source/player.h index 550aa1c..b0cafdd 100644 --- a/source/player.h +++ b/source/player.h @@ -1,14 +1,14 @@ #pragma once -#include // for SDL_Rect -#include // for Uint32 -#include // for unique_ptr, shared_ptr -#include // for string -#include // for vector -#include "animated_sprite.h" // for SpriteAnimated -#include "smart_sprite.h" // for SpriteAnimated -#include "enter_name.h" // for EnterName -#include "utils.h" // for Circle +#include // para SDL_Rect +#include // para Uint32 +#include // para unique_ptr, shared_ptr +#include // para string +#include // para vector +#include "animated_sprite.h" // para SpriteAnimated +#include "smart_sprite.h" // para SpriteAnimated +#include "enter_name.h" // para EnterName +#include "utils.h" // para Circle class Texture; enum class InputType : int; enum class ScoreboardMode; // lines 12-12 @@ -41,11 +41,11 @@ class Player { private: // Constantes - static constexpr int POWERUP_COUNTER_ = 1500; // Duración del estado PowerUp - static constexpr int INVULNERABLE_COUNTER_ = 200; // Duración del estado invulnerable - static constexpr int WIDTH_ = 30; // Anchura - static constexpr int HEIGHT_ = 30; // Altura - static constexpr float BASE_SPEED_ = 1.5f; // Velocidad base del jugador + static constexpr int POWERUP_COUNTER_ = 1500; // Duración del estado PowerUp + static constexpr int INVULNERABLE_COUNTER_ = 200; // Duración del estado invulnerable + static constexpr int WIDTH_ = 30; // Anchura + static constexpr int HEIGHT_ = 30; // Altura + static constexpr float BASE_SPEED_ = 1.5f; // Velocidad base del jugador // Objetos y punteros std::unique_ptr player_sprite_; // Sprite para dibujar el jugador diff --git a/source/resource.cpp b/source/resource.cpp index f311691..a2d75a0 100644 --- a/source/resource.cpp +++ b/source/resource.cpp @@ -113,7 +113,7 @@ std::shared_ptr Resource::getTextFile(const std::string &name) // Obtiene la animación a partir de un nombre AnimationsFileBuffer &Resource::getAnimation(const std::string &name) { - auto it = std::find_if(animations_.begin(), animations_.end(), [&name](auto &a) + auto it = std::find_if(animations_.begin(), animations_.end(), [&name](const auto &a) { return a.name == name; }); if (it != animations_.end()) diff --git a/source/scoreboard.cpp b/source/scoreboard.cpp index 45bfe79..f9deb70 100644 --- a/source/scoreboard.cpp +++ b/source/scoreboard.cpp @@ -1,17 +1,17 @@ #include "scoreboard.h" -#include // for SDL_BLENDMODE_BLEND -#include // for SDL_PIXELFORMAT_RGBA8888 -#include // for SDL_GetTicks -#include // for roundf +#include // para SDL_BLENDMODE_BLEND +#include // para SDL_PIXELFORMAT_RGBA8888 +#include // para SDL_GetTicks +#include // para roundf #include #include -#include "asset.h" // for Asset -#include "lang.h" // for getText -#include "resource.h" // for Resource +#include "asset.h" // para Asset +#include "lang.h" // para getText +#include "resource.h" // para Resource #include "screen.h" -#include "sprite.h" // for Sprite -#include "text.h" // for Text -#include "texture.h" // for Texture +#include "sprite.h" // para Sprite +#include "text.h" // para Text +#include "texture.h" // para Texture // [SINGLETON] Hay que definir las variables estáticas, desde el .h sólo la hemos declarado Scoreboard *Scoreboard::scoreboard_ = nullptr; diff --git a/source/scoreboard.h b/source/scoreboard.h index 58e1ec8..ddd52dc 100644 --- a/source/scoreboard.h +++ b/source/scoreboard.h @@ -1,13 +1,13 @@ #pragma once -#include // for SDL_Point, SDL_Rect -#include // for SDL_Renderer, SDL_Texture -#include // for Uint32 -#include // for SDL_GetTicks -#include // for unique_ptr, shared_ptr -#include // for string -#include // for vector -#include "utils.h" // for Color +#include // para SDL_Point, SDL_Rect +#include // para SDL_Renderer, SDL_Texture +#include // para Uint32 +#include // para SDL_GetTicks +#include // para unique_ptr, shared_ptr +#include // para string +#include // para vector +#include "utils.h" // para Color class Sprite; class Text; class Texture; diff --git a/source/screen.cpp b/source/screen.cpp index deed993..89a953c 100644 --- a/source/screen.cpp +++ b/source/screen.cpp @@ -1,24 +1,23 @@ #include "screen.h" -#include // for SDL_DISABLE, SDL_ENABLE -#include // for SDL_ShowCursor -#include // for SDL_PIXELFORMAT_RGBA8888 -#include // for SDL_GetTicks -#include // for max, min -#include // for basic_ifstream, ifstream -#include // for istreambuf_iterator, operator!= -#include // for basic_string, operator+, to_string, cha... -#include // for vector -#include "asset.h" // for Asset -#include "dbgtxt.h" // for dbg_print -#include "global_inputs.h" // for servicePressedCounter -#include "input.h" // for Input, inputs_e, INPUT_DO_NOT_ALLOW_REPEAT -#include "notifier.h" // for Notify -#include "on_screen_help.h" // for OnScreenHelp -#include "options.h" // for options -#include "param.h" // for param +#include // para SDL_DISABLE, SDL_ENABLE +#include // para SDL_ShowCursor +#include // para SDL_PIXELFORMAT_RGBA8888 +#include // para SDL_GetTicks +#include // para max, min +#include // para basic_ifstream, ifstream +#include // para istreambuf_iterator, operator!= +#include // para basic_string, operator+, to_string, cha... +#include // para vector +#include "asset.h" // para Asset +#include "dbgtxt.h" // para dbg_print +#include "global_inputs.h" // para servicePressedCounter +#include "input.h" // para Input, inputs_e, INPUT_DO_NOT_ALLOW_REPEAT +#include "notifier.h" // para Notify +#include "on_screen_help.h" // para OnScreenHelp +#include "options.h" // para options #ifndef NO_SHADERS -#include "jail_shader.h" // for init, render +#include "jail_shader.h" // para init, render #endif // [SINGLETON] Hay que definir las variables estáticas, desde el .h sólo la hemos declarado @@ -46,26 +45,12 @@ Screen *Screen::get() Screen::Screen(SDL_Window *window, SDL_Renderer *renderer) : window_(window), renderer_(renderer), - game_canvas_(SDL_CreateTexture(renderer_, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, param.game.width, param.game.height)), shader_canvas_(SDL_CreateTexture(renderer_, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, param.game.width, param.game.height)), - src_rect_({0, 0, param.game.width, param.game.height}), dst_rect_({0, 0, param.game.width, param.game.height}) { // Inicializa variables - flash_effect_.enabled = false; - flash_effect_.counter = 0; - flash_effect_.lenght = 0; - flash_effect_.color = Color(0xFF, 0xFF, 0xFF); - shake_effect_.enabled = false; - shake_effect_.desp = 2; - shake_effect_.delay = 3; - shake_effect_.counter = 0; - shake_effect_.lenght = 8; - shake_effect_.remaining = 0; - shake_effect_.originalPos = 0; - shake_effect_.originalWidth = param.game.width; SDL_DisplayMode DM; SDL_GetCurrentDisplayMode(0, &DM); info_resolution_ = std::to_string(DM.w) + " X " + std::to_string(DM.h) + " AT " + std::to_string(DM.refresh_rate) + " HZ"; diff --git a/source/screen.h b/source/screen.h index 653a3a0..c8a028c 100644 --- a/source/screen.h +++ b/source/screen.h @@ -1,13 +1,14 @@ #pragma once -#include // for SDL_BlendMode -#include // for SDL_Rect -#include // for SDL_Renderer, SDL_Texture -#include // for Uint32 -#include // for SDL_Window -#include // for basic_string, string -#include "utils.h" // for Color +#include // para SDL_BlendMode +#include // para SDL_Rect +#include // para SDL_Renderer, SDL_Texture +#include // para Uint32 +#include // para SDL_Window +#include // para basic_string, string +#include "utils.h" // para Color #include +#include "param.h" // para param enum class ScreenFilter : int { @@ -40,7 +41,7 @@ private: bool attenuate_effect_ = false; // Indica si la pantalla ha de estar atenuada Uint32 fps_ticks_ = 0; // Ticks para contar los frames por segundo int fps_counter_ = 0; // Contador de frames por segundo - int fps_; // Frames calculados en el último segundo + int fps_ = 0; // Frames calculados en el último segundo std::string info_resolution_; // Texto con la informacion de la pantalla #ifdef DEBUG bool show_info_ = true; // Indica si ha de mostrar/ocultar la información de la pantalla @@ -54,6 +55,10 @@ private: int counter; // Contador para el efecto int lenght; // Duración del efecto Color color; // Color del efecto + + // Constructor + FlashEffect(bool en = false, int cnt = 0, int len = 0, Color col = Color(0xFF, 0xFF, 0xFF)) + : enabled(en), counter(cnt), lenght(len), color(col) {} }; struct ShakeEffect @@ -66,6 +71,10 @@ private: int originalPos; // Posición inicial de la pantalla para dejarla igual tras el desplazamiento int originalWidth; // Anchura inicial de la pantalla para dejarla igual tras el desplazamiento bool enabled; // Indica si el efecto está activo + + // Constructor + ShakeEffect(bool en = false, int dp = 2, int dl = 3, int cnt = 0, int len = 8, int rem = 0, int origPos = 0, int origWidth = param.game.width) + : desp(dp), delay(dl), counter(cnt), lenght(len), remaining(rem), originalPos(origPos), originalWidth(origWidth), enabled(en) {} }; // Variables - Efectos diff --git a/source/smart_sprite.h b/source/smart_sprite.h index c92bb5d..6ec7348 100644 --- a/source/smart_sprite.h +++ b/source/smart_sprite.h @@ -1,7 +1,7 @@ #pragma once -#include // for shared_ptr -#include "animated_sprite.h" // for SpriteAnimated +#include // para shared_ptr +#include "animated_sprite.h" // para SpriteAnimated class Texture; // Clase SpriteSmart diff --git a/source/sprite.h b/source/sprite.h index 85b39f0..ddfdb71 100644 --- a/source/sprite.h +++ b/source/sprite.h @@ -1,6 +1,6 @@ #pragma once -#include // for SDL_Rect, SDL_Point +#include // para SDL_Rect, SDL_Point #include "texture.h" #include diff --git a/source/stb_image.h b/source/stb_image.h index 9eedabe..1f64609 100644 --- a/source/stb_image.h +++ b/source/stb_image.h @@ -377,10 +377,10 @@ enum { STBI_default = 0, // only used for desired_channels - STBI_grey = 1, + STBI_grey = 1, STBI_grey_alpha = 2, - STBI_rgb = 3, - STBI_rgb_alpha = 4 + STBI_rgb = 3, + STBI_rgb_alpha = 4 }; #include @@ -388,7 +388,8 @@ typedef unsigned char stbi_uc; typedef unsigned short stbi_us; #ifdef __cplusplus -extern "C" { +extern "C" +{ #endif #ifndef STBIDEF @@ -399,55 +400,55 @@ extern "C" { #endif #endif -////////////////////////////////////////////////////////////////////////////// -// -// PRIMARY API - works on images of any type -// + ////////////////////////////////////////////////////////////////////////////// + // + // PRIMARY API - works on images of any type + // -// -// load image by filename, open file, or memory buffer -// + // + // load image by filename, open file, or memory buffer + // -typedef struct -{ - int (*read) (void *user,char *data,int size); // fill 'data' with 'size' bytes. return number of bytes actually read - void (*skip) (void *user,int n); // skip the next 'n' bytes, or 'unget' the last -n bytes if negative - int (*eof) (void *user); // returns nonzero if we are at end of file/data -} stbi_io_callbacks; + typedef struct + { + int (*read)(void *user, char *data, int size); // fill 'data' with 'size' bytes. return number of bytes actually read + void (*skip)(void *user, int n); // skip the next 'n' bytes, or 'unget' the last -n bytes if negative + int (*eof)(void *user); // returns nonzero if we are at end of file/data + } stbi_io_callbacks; -//////////////////////////////////// -// -// 8-bits-per-channel interface -// + //////////////////////////////////// + // + // 8-bits-per-channel interface + // -STBIDEF stbi_uc *stbi_load_from_memory (stbi_uc const *buffer, int len , int *x, int *y, int *channels_in_file, int desired_channels); -STBIDEF stbi_uc *stbi_load_from_callbacks(stbi_io_callbacks const *clbk , void *user, int *x, int *y, int *channels_in_file, int desired_channels); + STBIDEF stbi_uc *stbi_load_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *channels_in_file, int desired_channels); + STBIDEF stbi_uc *stbi_load_from_callbacks(stbi_io_callbacks const *clbk, void *user, int *x, int *y, int *channels_in_file, int desired_channels); #ifndef STBI_NO_STDIO -STBIDEF stbi_uc *stbi_load (char const *filename, int *x, int *y, int *channels_in_file, int desired_channels); -STBIDEF stbi_uc *stbi_load_from_file (FILE *f, int *x, int *y, int *channels_in_file, int desired_channels); -// for stbi_load_from_file, file pointer is left pointing immediately after image + STBIDEF stbi_uc *stbi_load(char const *filename, int *x, int *y, int *channels_in_file, int desired_channels); + STBIDEF stbi_uc *stbi_load_from_file(FILE *f, int *x, int *y, int *channels_in_file, int desired_channels); +// para stbi_load_from_file, file pointer is left pointing immediately after image #endif #ifndef STBI_NO_GIF -STBIDEF stbi_uc *stbi_load_gif_from_memory(stbi_uc const *buffer, int len, int **delays, int *x, int *y, int *z, int *comp, int req_comp); + STBIDEF stbi_uc *stbi_load_gif_from_memory(stbi_uc const *buffer, int len, int **delays, int *x, int *y, int *z, int *comp, int req_comp); #endif #ifdef STBI_WINDOWS_UTF8 -STBIDEF int stbi_convert_wchar_to_utf8(char *buffer, size_t bufferlen, const wchar_t* input); + STBIDEF int stbi_convert_wchar_to_utf8(char *buffer, size_t bufferlen, const wchar_t *input); #endif -//////////////////////////////////// -// -// 16-bits-per-channel interface -// + //////////////////////////////////// + // + // 16-bits-per-channel interface + // -STBIDEF stbi_us *stbi_load_16_from_memory (stbi_uc const *buffer, int len, int *x, int *y, int *channels_in_file, int desired_channels); -STBIDEF stbi_us *stbi_load_16_from_callbacks(stbi_io_callbacks const *clbk, void *user, int *x, int *y, int *channels_in_file, int desired_channels); + STBIDEF stbi_us *stbi_load_16_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *channels_in_file, int desired_channels); + STBIDEF stbi_us *stbi_load_16_from_callbacks(stbi_io_callbacks const *clbk, void *user, int *x, int *y, int *channels_in_file, int desired_channels); #ifndef STBI_NO_STDIO -STBIDEF stbi_us *stbi_load_16 (char const *filename, int *x, int *y, int *channels_in_file, int desired_channels); -STBIDEF stbi_us *stbi_load_from_file_16(FILE *f, int *x, int *y, int *channels_in_file, int desired_channels); + STBIDEF stbi_us *stbi_load_16(char const *filename, int *x, int *y, int *channels_in_file, int desired_channels); + STBIDEF stbi_us *stbi_load_from_file_16(FILE *f, int *x, int *y, int *channels_in_file, int desired_channels); #endif //////////////////////////////////// @@ -455,85 +456,81 @@ STBIDEF stbi_us *stbi_load_from_file_16(FILE *f, int *x, int *y, int *channels_i // float-per-channel interface // #ifndef STBI_NO_LINEAR - STBIDEF float *stbi_loadf_from_memory (stbi_uc const *buffer, int len, int *x, int *y, int *channels_in_file, int desired_channels); - STBIDEF float *stbi_loadf_from_callbacks (stbi_io_callbacks const *clbk, void *user, int *x, int *y, int *channels_in_file, int desired_channels); + STBIDEF float *stbi_loadf_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *channels_in_file, int desired_channels); + STBIDEF float *stbi_loadf_from_callbacks(stbi_io_callbacks const *clbk, void *user, int *x, int *y, int *channels_in_file, int desired_channels); - #ifndef STBI_NO_STDIO - STBIDEF float *stbi_loadf (char const *filename, int *x, int *y, int *channels_in_file, int desired_channels); - STBIDEF float *stbi_loadf_from_file (FILE *f, int *x, int *y, int *channels_in_file, int desired_channels); - #endif +#ifndef STBI_NO_STDIO + STBIDEF float *stbi_loadf(char const *filename, int *x, int *y, int *channels_in_file, int desired_channels); + STBIDEF float *stbi_loadf_from_file(FILE *f, int *x, int *y, int *channels_in_file, int desired_channels); +#endif #endif #ifndef STBI_NO_HDR - STBIDEF void stbi_hdr_to_ldr_gamma(float gamma); - STBIDEF void stbi_hdr_to_ldr_scale(float scale); + STBIDEF void stbi_hdr_to_ldr_gamma(float gamma); + STBIDEF void stbi_hdr_to_ldr_scale(float scale); #endif // STBI_NO_HDR #ifndef STBI_NO_LINEAR - STBIDEF void stbi_ldr_to_hdr_gamma(float gamma); - STBIDEF void stbi_ldr_to_hdr_scale(float scale); + STBIDEF void stbi_ldr_to_hdr_gamma(float gamma); + STBIDEF void stbi_ldr_to_hdr_scale(float scale); #endif // STBI_NO_LINEAR -// stbi_is_hdr is always defined, but always returns false if STBI_NO_HDR -STBIDEF int stbi_is_hdr_from_callbacks(stbi_io_callbacks const *clbk, void *user); -STBIDEF int stbi_is_hdr_from_memory(stbi_uc const *buffer, int len); + // stbi_is_hdr is always defined, but always returns false if STBI_NO_HDR + STBIDEF int stbi_is_hdr_from_callbacks(stbi_io_callbacks const *clbk, void *user); + STBIDEF int stbi_is_hdr_from_memory(stbi_uc const *buffer, int len); #ifndef STBI_NO_STDIO -STBIDEF int stbi_is_hdr (char const *filename); -STBIDEF int stbi_is_hdr_from_file(FILE *f); + STBIDEF int stbi_is_hdr(char const *filename); + STBIDEF int stbi_is_hdr_from_file(FILE *f); #endif // STBI_NO_STDIO + // get a VERY brief reason for failure + // on most compilers (and ALL modern mainstream compilers) this is threadsafe + STBIDEF const char *stbi_failure_reason(void); -// get a VERY brief reason for failure -// on most compilers (and ALL modern mainstream compilers) this is threadsafe -STBIDEF const char *stbi_failure_reason (void); + // free the loaded image -- this is just free() + STBIDEF void stbi_image_free(void *retval_from_stbi_load); -// free the loaded image -- this is just free() -STBIDEF void stbi_image_free (void *retval_from_stbi_load); - -// get image dimensions & components without fully decoding -STBIDEF int stbi_info_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *comp); -STBIDEF int stbi_info_from_callbacks(stbi_io_callbacks const *clbk, void *user, int *x, int *y, int *comp); -STBIDEF int stbi_is_16_bit_from_memory(stbi_uc const *buffer, int len); -STBIDEF int stbi_is_16_bit_from_callbacks(stbi_io_callbacks const *clbk, void *user); + // get image dimensions & components without fully decoding + STBIDEF int stbi_info_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *comp); + STBIDEF int stbi_info_from_callbacks(stbi_io_callbacks const *clbk, void *user, int *x, int *y, int *comp); + STBIDEF int stbi_is_16_bit_from_memory(stbi_uc const *buffer, int len); + STBIDEF int stbi_is_16_bit_from_callbacks(stbi_io_callbacks const *clbk, void *user); #ifndef STBI_NO_STDIO -STBIDEF int stbi_info (char const *filename, int *x, int *y, int *comp); -STBIDEF int stbi_info_from_file (FILE *f, int *x, int *y, int *comp); -STBIDEF int stbi_is_16_bit (char const *filename); -STBIDEF int stbi_is_16_bit_from_file(FILE *f); + STBIDEF int stbi_info(char const *filename, int *x, int *y, int *comp); + STBIDEF int stbi_info_from_file(FILE *f, int *x, int *y, int *comp); + STBIDEF int stbi_is_16_bit(char const *filename); + STBIDEF int stbi_is_16_bit_from_file(FILE *f); #endif + // para image formats that explicitly notate that they have premultiplied alpha, + // we just return the colors as stored in the file. set this flag to force + // unpremultiplication. results are undefined if the unpremultiply overflow. + STBIDEF void stbi_set_unpremultiply_on_load(int flag_true_if_should_unpremultiply); + // indicate whether we should process iphone images back to canonical format, + // or just pass them through "as-is" + STBIDEF void stbi_convert_iphone_png_to_rgb(int flag_true_if_should_convert); -// for image formats that explicitly notate that they have premultiplied alpha, -// we just return the colors as stored in the file. set this flag to force -// unpremultiplication. results are undefined if the unpremultiply overflow. -STBIDEF void stbi_set_unpremultiply_on_load(int flag_true_if_should_unpremultiply); + // flip the image vertically, so the first pixel in the output array is the bottom left + STBIDEF void stbi_set_flip_vertically_on_load(int flag_true_if_should_flip); -// indicate whether we should process iphone images back to canonical format, -// or just pass them through "as-is" -STBIDEF void stbi_convert_iphone_png_to_rgb(int flag_true_if_should_convert); + // as above, but only applies to images loaded on the thread that calls the function + // this function is only available if your compiler supports thread-local variables; + // calling it will fail to link if your compiler doesn't + STBIDEF void stbi_set_unpremultiply_on_load_thread(int flag_true_if_should_unpremultiply); + STBIDEF void stbi_convert_iphone_png_to_rgb_thread(int flag_true_if_should_convert); + STBIDEF void stbi_set_flip_vertically_on_load_thread(int flag_true_if_should_flip); -// flip the image vertically, so the first pixel in the output array is the bottom left -STBIDEF void stbi_set_flip_vertically_on_load(int flag_true_if_should_flip); + // ZLIB client - used by PNG, available for other purposes -// as above, but only applies to images loaded on the thread that calls the function -// this function is only available if your compiler supports thread-local variables; -// calling it will fail to link if your compiler doesn't -STBIDEF void stbi_set_unpremultiply_on_load_thread(int flag_true_if_should_unpremultiply); -STBIDEF void stbi_convert_iphone_png_to_rgb_thread(int flag_true_if_should_convert); -STBIDEF void stbi_set_flip_vertically_on_load_thread(int flag_true_if_should_flip); - -// ZLIB client - used by PNG, available for other purposes - -STBIDEF char *stbi_zlib_decode_malloc_guesssize(const char *buffer, int len, int initial_size, int *outlen); -STBIDEF char *stbi_zlib_decode_malloc_guesssize_headerflag(const char *buffer, int len, int initial_size, int *outlen, int parse_header); -STBIDEF char *stbi_zlib_decode_malloc(const char *buffer, int len, int *outlen); -STBIDEF int stbi_zlib_decode_buffer(char *obuffer, int olen, const char *ibuffer, int ilen); - -STBIDEF char *stbi_zlib_decode_noheader_malloc(const char *buffer, int len, int *outlen); -STBIDEF int stbi_zlib_decode_noheader_buffer(char *obuffer, int olen, const char *ibuffer, int ilen); + STBIDEF char *stbi_zlib_decode_malloc_guesssize(const char *buffer, int len, int initial_size, int *outlen); + STBIDEF char *stbi_zlib_decode_malloc_guesssize_headerflag(const char *buffer, int len, int initial_size, int *outlen, int parse_header); + STBIDEF char *stbi_zlib_decode_malloc(const char *buffer, int len, int *outlen); + STBIDEF int stbi_zlib_decode_buffer(char *obuffer, int olen, const char *ibuffer, int ilen); + STBIDEF char *stbi_zlib_decode_noheader_malloc(const char *buffer, int len, int *outlen); + STBIDEF int stbi_zlib_decode_noheader_buffer(char *obuffer, int olen, const char *ibuffer, int ilen); #ifdef __cplusplus } @@ -546,44 +543,40 @@ STBIDEF int stbi_zlib_decode_noheader_buffer(char *obuffer, int olen, const ch #ifdef STB_IMAGE_IMPLEMENTATION -#if defined(STBI_ONLY_JPEG) || defined(STBI_ONLY_PNG) || defined(STBI_ONLY_BMP) \ - || defined(STBI_ONLY_TGA) || defined(STBI_ONLY_GIF) || defined(STBI_ONLY_PSD) \ - || defined(STBI_ONLY_HDR) || defined(STBI_ONLY_PIC) || defined(STBI_ONLY_PNM) \ - || defined(STBI_ONLY_ZLIB) - #ifndef STBI_ONLY_JPEG - #define STBI_NO_JPEG - #endif - #ifndef STBI_ONLY_PNG - #define STBI_NO_PNG - #endif - #ifndef STBI_ONLY_BMP - #define STBI_NO_BMP - #endif - #ifndef STBI_ONLY_PSD - #define STBI_NO_PSD - #endif - #ifndef STBI_ONLY_TGA - #define STBI_NO_TGA - #endif - #ifndef STBI_ONLY_GIF - #define STBI_NO_GIF - #endif - #ifndef STBI_ONLY_HDR - #define STBI_NO_HDR - #endif - #ifndef STBI_ONLY_PIC - #define STBI_NO_PIC - #endif - #ifndef STBI_ONLY_PNM - #define STBI_NO_PNM - #endif +#if defined(STBI_ONLY_JPEG) || defined(STBI_ONLY_PNG) || defined(STBI_ONLY_BMP) || defined(STBI_ONLY_TGA) || defined(STBI_ONLY_GIF) || defined(STBI_ONLY_PSD) || defined(STBI_ONLY_HDR) || defined(STBI_ONLY_PIC) || defined(STBI_ONLY_PNM) || defined(STBI_ONLY_ZLIB) +#ifndef STBI_ONLY_JPEG +#define STBI_NO_JPEG +#endif +#ifndef STBI_ONLY_PNG +#define STBI_NO_PNG +#endif +#ifndef STBI_ONLY_BMP +#define STBI_NO_BMP +#endif +#ifndef STBI_ONLY_PSD +#define STBI_NO_PSD +#endif +#ifndef STBI_ONLY_TGA +#define STBI_NO_TGA +#endif +#ifndef STBI_ONLY_GIF +#define STBI_NO_GIF +#endif +#ifndef STBI_ONLY_HDR +#define STBI_NO_HDR +#endif +#ifndef STBI_ONLY_PIC +#define STBI_NO_PIC +#endif +#ifndef STBI_ONLY_PNM +#define STBI_NO_PNM +#endif #endif #if defined(STBI_NO_PNG) && !defined(STBI_SUPPORT_ZLIB) && !defined(STBI_NO_ZLIB) #define STBI_NO_ZLIB #endif - #include #include // ptrdiff_t on osx #include @@ -591,7 +584,7 @@ STBIDEF int stbi_zlib_decode_noheader_buffer(char *obuffer, int olen, const ch #include #if !defined(STBI_NO_LINEAR) || !defined(STBI_NO_HDR) -#include // ldexp, pow +#include // ldexp, pow #endif #ifndef STBI_NO_STDIO @@ -609,55 +602,54 @@ STBIDEF int stbi_zlib_decode_noheader_buffer(char *obuffer, int olen, const ch #define STBI_EXTERN extern #endif - #ifndef _MSC_VER - #ifdef __cplusplus - #define stbi_inline inline - #else - #define stbi_inline - #endif +#ifdef __cplusplus +#define stbi_inline inline #else - #define stbi_inline __forceinline +#define stbi_inline +#endif +#else +#define stbi_inline __forceinline #endif #ifndef STBI_NO_THREAD_LOCALS - #if defined(__cplusplus) && __cplusplus >= 201103L - #define STBI_THREAD_LOCAL thread_local - #elif defined(__GNUC__) && __GNUC__ < 5 - #define STBI_THREAD_LOCAL __thread - #elif defined(_MSC_VER) - #define STBI_THREAD_LOCAL __declspec(thread) - #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 201112L && !defined(__STDC_NO_THREADS__) - #define STBI_THREAD_LOCAL _Thread_local - #endif +#if defined(__cplusplus) && __cplusplus >= 201103L +#define STBI_THREAD_LOCAL thread_local +#elif defined(__GNUC__) && __GNUC__ < 5 +#define STBI_THREAD_LOCAL __thread +#elif defined(_MSC_VER) +#define STBI_THREAD_LOCAL __declspec(thread) +#elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L && !defined(__STDC_NO_THREADS__) +#define STBI_THREAD_LOCAL _Thread_local +#endif - #ifndef STBI_THREAD_LOCAL - #if defined(__GNUC__) - #define STBI_THREAD_LOCAL __thread - #endif - #endif +#ifndef STBI_THREAD_LOCAL +#if defined(__GNUC__) +#define STBI_THREAD_LOCAL __thread +#endif +#endif #endif #if defined(_MSC_VER) || defined(__SYMBIAN32__) typedef unsigned short stbi__uint16; -typedef signed short stbi__int16; -typedef unsigned int stbi__uint32; -typedef signed int stbi__int32; +typedef signed short stbi__int16; +typedef unsigned int stbi__uint32; +typedef signed int stbi__int32; #else #include typedef uint16_t stbi__uint16; -typedef int16_t stbi__int16; +typedef int16_t stbi__int16; typedef uint32_t stbi__uint32; -typedef int32_t stbi__int32; +typedef int32_t stbi__int32; #endif // should produce compiler error if size is wrong -typedef unsigned char validate_uint32[sizeof(stbi__uint32)==4 ? 1 : -1]; +typedef unsigned char validate_uint32[sizeof(stbi__uint32) == 4 ? 1 : -1]; #ifdef _MSC_VER -#define STBI_NOTUSED(v) (void)(v) +#define STBI_NOTUSED(v) (void)(v) #else -#define STBI_NOTUSED(v) (void)sizeof(v) +#define STBI_NOTUSED(v) (void)sizeof(v) #endif #ifdef _MSC_VER @@ -665,9 +657,9 @@ typedef unsigned char validate_uint32[sizeof(stbi__uint32)==4 ? 1 : -1]; #endif #ifdef STBI_HAS_LROTL - #define stbi_lrot(x,y) _lrotl(x,y) +#define stbi_lrot(x, y) _lrotl(x, y) #else - #define stbi_lrot(x,y) (((x) << (y)) | ((x) >> (-(y) & 31))) +#define stbi_lrot(x, y) (((x) << (y)) | ((x) >> (-(y) & 31))) #endif #if defined(STBI_MALLOC) && defined(STBI_FREE) && (defined(STBI_REALLOC) || defined(STBI_REALLOC_SIZED)) @@ -679,13 +671,13 @@ typedef unsigned char validate_uint32[sizeof(stbi__uint32)==4 ? 1 : -1]; #endif #ifndef STBI_MALLOC -#define STBI_MALLOC(sz) malloc(sz) -#define STBI_REALLOC(p,newsz) realloc(p,newsz) -#define STBI_FREE(p) free(p) +#define STBI_MALLOC(sz) malloc(sz) +#define STBI_REALLOC(p, newsz) realloc(p, newsz) +#define STBI_FREE(p) free(p) #endif #ifndef STBI_REALLOC_SIZED -#define STBI_REALLOC_SIZED(p,oldsz,newsz) STBI_REALLOC(p,newsz) +#define STBI_REALLOC_SIZED(p, oldsz, newsz) STBI_REALLOC(p, newsz) #endif // x86/x64 detection @@ -727,12 +719,12 @@ typedef unsigned char validate_uint32[sizeof(stbi__uint32)==4 ? 1 : -1]; #ifdef _MSC_VER -#if _MSC_VER >= 1400 // not VC6 -#include // __cpuid +#if _MSC_VER >= 1400 // not VC6 +#include // __cpuid static int stbi__cpuid3(void) { int info[4]; - __cpuid(info,1); + __cpuid(info, 1); return info[3]; } #else @@ -819,7 +811,6 @@ typedef struct stbi_uc *img_buffer_original, *img_buffer_original_end; } stbi__context; - static void stbi__refill_buffer(stbi__context *s); // initialize a memory-decode context @@ -828,8 +819,8 @@ static void stbi__start_mem(stbi__context *s, stbi_uc const *buffer, int len) s->io.read = NULL; s->read_from_callbacks = 0; s->callback_already_read = 0; - s->img_buffer = s->img_buffer_original = (stbi_uc *) buffer; - s->img_buffer_end = s->img_buffer_original_end = (stbi_uc *) buffer+len; + s->img_buffer = s->img_buffer_original = (stbi_uc *)buffer; + s->img_buffer_end = s->img_buffer_original_end = (stbi_uc *)buffer + len; } // initialize a callback-based context @@ -849,37 +840,38 @@ static void stbi__start_callbacks(stbi__context *s, stbi_io_callbacks *c, void * static int stbi__stdio_read(void *user, char *data, int size) { - return (int) fread(data,1,size,(FILE*) user); + return (int)fread(data, 1, size, (FILE *)user); } static void stbi__stdio_skip(void *user, int n) { int ch; - fseek((FILE*) user, n, SEEK_CUR); - ch = fgetc((FILE*) user); /* have to read a byte to reset feof()'s flag */ - if (ch != EOF) { - ungetc(ch, (FILE *) user); /* push byte back onto stream if valid. */ + fseek((FILE *)user, n, SEEK_CUR); + ch = fgetc((FILE *)user); /* have to read a byte to reset feof()'s flag */ + if (ch != EOF) + { + ungetc(ch, (FILE *)user); /* push byte back onto stream if valid. */ } } static int stbi__stdio_eof(void *user) { - return feof((FILE*) user) || ferror((FILE *) user); + return feof((FILE *)user) || ferror((FILE *)user); } static stbi_io_callbacks stbi__stdio_callbacks = -{ - stbi__stdio_read, - stbi__stdio_skip, - stbi__stdio_eof, + { + stbi__stdio_read, + stbi__stdio_skip, + stbi__stdio_eof, }; static void stbi__start_file(stbi__context *s, FILE *f) { - stbi__start_callbacks(s, &stbi__stdio_callbacks, (void *) f); + stbi__start_callbacks(s, &stbi__stdio_callbacks, (void *)f); } -//static void stop_file(stbi__context *s) { } +// static void stop_file(stbi__context *s) { } #endif // !STBI_NO_STDIO @@ -906,68 +898,68 @@ typedef struct } stbi__result_info; #ifndef STBI_NO_JPEG -static int stbi__jpeg_test(stbi__context *s); -static void *stbi__jpeg_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri); -static int stbi__jpeg_info(stbi__context *s, int *x, int *y, int *comp); +static int stbi__jpeg_test(stbi__context *s); +static void *stbi__jpeg_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri); +static int stbi__jpeg_info(stbi__context *s, int *x, int *y, int *comp); #endif #ifndef STBI_NO_PNG -static int stbi__png_test(stbi__context *s); -static void *stbi__png_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri); -static int stbi__png_info(stbi__context *s, int *x, int *y, int *comp); -static int stbi__png_is16(stbi__context *s); +static int stbi__png_test(stbi__context *s); +static void *stbi__png_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri); +static int stbi__png_info(stbi__context *s, int *x, int *y, int *comp); +static int stbi__png_is16(stbi__context *s); #endif #ifndef STBI_NO_BMP -static int stbi__bmp_test(stbi__context *s); -static void *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri); -static int stbi__bmp_info(stbi__context *s, int *x, int *y, int *comp); +static int stbi__bmp_test(stbi__context *s); +static void *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri); +static int stbi__bmp_info(stbi__context *s, int *x, int *y, int *comp); #endif #ifndef STBI_NO_TGA -static int stbi__tga_test(stbi__context *s); -static void *stbi__tga_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri); -static int stbi__tga_info(stbi__context *s, int *x, int *y, int *comp); +static int stbi__tga_test(stbi__context *s); +static void *stbi__tga_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri); +static int stbi__tga_info(stbi__context *s, int *x, int *y, int *comp); #endif #ifndef STBI_NO_PSD -static int stbi__psd_test(stbi__context *s); -static void *stbi__psd_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri, int bpc); -static int stbi__psd_info(stbi__context *s, int *x, int *y, int *comp); -static int stbi__psd_is16(stbi__context *s); +static int stbi__psd_test(stbi__context *s); +static void *stbi__psd_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri, int bpc); +static int stbi__psd_info(stbi__context *s, int *x, int *y, int *comp); +static int stbi__psd_is16(stbi__context *s); #endif #ifndef STBI_NO_HDR -static int stbi__hdr_test(stbi__context *s); -static float *stbi__hdr_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri); -static int stbi__hdr_info(stbi__context *s, int *x, int *y, int *comp); +static int stbi__hdr_test(stbi__context *s); +static float *stbi__hdr_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri); +static int stbi__hdr_info(stbi__context *s, int *x, int *y, int *comp); #endif #ifndef STBI_NO_PIC -static int stbi__pic_test(stbi__context *s); -static void *stbi__pic_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri); -static int stbi__pic_info(stbi__context *s, int *x, int *y, int *comp); +static int stbi__pic_test(stbi__context *s); +static void *stbi__pic_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri); +static int stbi__pic_info(stbi__context *s, int *x, int *y, int *comp); #endif #ifndef STBI_NO_GIF -static int stbi__gif_test(stbi__context *s); -static void *stbi__gif_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri); -static void *stbi__load_gif_main(stbi__context *s, int **delays, int *x, int *y, int *z, int *comp, int req_comp); -static int stbi__gif_info(stbi__context *s, int *x, int *y, int *comp); +static int stbi__gif_test(stbi__context *s); +static void *stbi__gif_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri); +static void *stbi__load_gif_main(stbi__context *s, int **delays, int *x, int *y, int *z, int *comp, int req_comp); +static int stbi__gif_info(stbi__context *s, int *x, int *y, int *comp); #endif #ifndef STBI_NO_PNM -static int stbi__pnm_test(stbi__context *s); -static void *stbi__pnm_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri); -static int stbi__pnm_info(stbi__context *s, int *x, int *y, int *comp); -static int stbi__pnm_is16(stbi__context *s); +static int stbi__pnm_test(stbi__context *s); +static void *stbi__pnm_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri); +static int stbi__pnm_info(stbi__context *s, int *x, int *y, int *comp); +static int stbi__pnm_is16(stbi__context *s); #endif static #ifdef STBI_THREAD_LOCAL -STBI_THREAD_LOCAL + STBI_THREAD_LOCAL #endif -const char *stbi__g_failure_reason; + const char *stbi__g_failure_reason; STBIDEF const char *stbi_failure_reason(void) { @@ -984,7 +976,7 @@ static int stbi__err(const char *str) static void *stbi__malloc(size_t size) { - return STBI_MALLOC(size); + return STBI_MALLOC(size); } // stb_image uses ints pervasively, including for offset calculations. @@ -1001,7 +993,8 @@ static void *stbi__malloc(size_t size) // negative terms are considered invalid. static int stbi__addsizes_valid(int a, int b) { - if (b < 0) return 0; + if (b < 0) + return 0; // now 0 <= b <= INT_MAX, hence also // 0 <= INT_MAX - b <= INTMAX. // And "a + b <= INT_MAX" (which might overflow) is the @@ -1013,33 +1006,35 @@ static int stbi__addsizes_valid(int a, int b) // negative factors are considered invalid. static int stbi__mul2sizes_valid(int a, int b) { - if (a < 0 || b < 0) return 0; - if (b == 0) return 1; // mul-by-0 is always safe + if (a < 0 || b < 0) + return 0; + if (b == 0) + return 1; // mul-by-0 is always safe // portable way to check for no overflows in a*b - return a <= INT_MAX/b; + return a <= INT_MAX / b; } #if !defined(STBI_NO_JPEG) || !defined(STBI_NO_PNG) || !defined(STBI_NO_TGA) || !defined(STBI_NO_HDR) // returns 1 if "a*b + add" has no negative terms/factors and doesn't overflow static int stbi__mad2sizes_valid(int a, int b, int add) { - return stbi__mul2sizes_valid(a, b) && stbi__addsizes_valid(a*b, add); + return stbi__mul2sizes_valid(a, b) && stbi__addsizes_valid(a * b, add); } #endif // returns 1 if "a*b*c + add" has no negative terms/factors and doesn't overflow static int stbi__mad3sizes_valid(int a, int b, int c, int add) { - return stbi__mul2sizes_valid(a, b) && stbi__mul2sizes_valid(a*b, c) && - stbi__addsizes_valid(a*b*c, add); + return stbi__mul2sizes_valid(a, b) && stbi__mul2sizes_valid(a * b, c) && + stbi__addsizes_valid(a * b * c, add); } // returns 1 if "a*b*c*d + add" has no negative terms/factors and doesn't overflow #if !defined(STBI_NO_LINEAR) || !defined(STBI_NO_HDR) || !defined(STBI_NO_PNM) static int stbi__mad4sizes_valid(int a, int b, int c, int d, int add) { - return stbi__mul2sizes_valid(a, b) && stbi__mul2sizes_valid(a*b, c) && - stbi__mul2sizes_valid(a*b*c, d) && stbi__addsizes_valid(a*b*c*d, add); + return stbi__mul2sizes_valid(a, b) && stbi__mul2sizes_valid(a * b, c) && + stbi__mul2sizes_valid(a * b * c, d) && stbi__addsizes_valid(a * b * c * d, add); } #endif @@ -1047,39 +1042,47 @@ static int stbi__mad4sizes_valid(int a, int b, int c, int d, int add) // mallocs with size overflow checking static void *stbi__malloc_mad2(int a, int b, int add) { - if (!stbi__mad2sizes_valid(a, b, add)) return NULL; - return stbi__malloc(a*b + add); + if (!stbi__mad2sizes_valid(a, b, add)) + return NULL; + return stbi__malloc(a * b + add); } #endif static void *stbi__malloc_mad3(int a, int b, int c, int add) { - if (!stbi__mad3sizes_valid(a, b, c, add)) return NULL; - return stbi__malloc(a*b*c + add); + if (!stbi__mad3sizes_valid(a, b, c, add)) + return NULL; + return stbi__malloc(a * b * c + add); } #if !defined(STBI_NO_LINEAR) || !defined(STBI_NO_HDR) || !defined(STBI_NO_PNM) static void *stbi__malloc_mad4(int a, int b, int c, int d, int add) { - if (!stbi__mad4sizes_valid(a, b, c, d, add)) return NULL; - return stbi__malloc(a*b*c*d + add); + if (!stbi__mad4sizes_valid(a, b, c, d, add)) + return NULL; + return stbi__malloc(a * b * c * d + add); } #endif // returns 1 if the sum of two signed ints is valid (between -2^31 and 2^31-1 inclusive), 0 on overflow. static int stbi__addints_valid(int a, int b) { - if ((a >= 0) != (b >= 0)) return 1; // a and b have different signs, so no overflow - if (a < 0 && b < 0) return a >= INT_MIN - b; // same as a + b >= INT_MIN; INT_MIN - b cannot overflow since b < 0. + if ((a >= 0) != (b >= 0)) + return 1; // a and b have different signs, so no overflow + if (a < 0 && b < 0) + return a >= INT_MIN - b; // same as a + b >= INT_MIN; INT_MIN - b cannot overflow since b < 0. return a <= INT_MAX - b; } // returns 1 if the product of two ints fits in a signed short, 0 on overflow. static int stbi__mul2shorts_valid(int a, int b) { - if (b == 0 || b == -1) return 1; // multiplication by 0 is always 0; check for -1 so SHRT_MIN/b doesn't overflow - if ((a >= 0) == (b >= 0)) return a <= SHRT_MAX/b; // product is positive, so similar to mul2sizes_valid - if (b < 0) return a <= SHRT_MIN / b; // same as a * b >= SHRT_MIN + if (b == 0 || b == -1) + return 1; // multiplication by 0 is always 0; check for -1 so SHRT_MIN/b doesn't overflow + if ((a >= 0) == (b >= 0)) + return a <= SHRT_MAX / b; // product is positive, so similar to mul2sizes_valid + if (b < 0) + return a <= SHRT_MIN / b; // same as a * b >= SHRT_MIN return a >= SHRT_MIN / b; } @@ -1088,15 +1091,15 @@ static int stbi__mul2shorts_valid(int a, int b) // stbi__errpuc - error returning pointer to unsigned char #ifdef STBI_NO_FAILURE_STRINGS - #define stbi__err(x,y) 0 +#define stbi__err(x, y) 0 #elif defined(STBI_FAILURE_USERMSG) - #define stbi__err(x,y) stbi__err(y) +#define stbi__err(x, y) stbi__err(y) #else - #define stbi__err(x,y) stbi__err(x) +#define stbi__err(x, y) stbi__err(x) #endif -#define stbi__errpf(x,y) ((float *)(size_t) (stbi__err(x,y)?NULL:NULL)) -#define stbi__errpuc(x,y) ((unsigned char *)(size_t) (stbi__err(x,y)?NULL:NULL)) +#define stbi__errpf(x, y) ((float *)(size_t)(stbi__err(x, y) ? NULL : NULL)) +#define stbi__errpuc(x, y) ((unsigned char *)(size_t)(stbi__err(x, y) ? NULL : NULL)) STBIDEF void stbi_image_free(void *retval_from_stbi_load) { @@ -1104,11 +1107,11 @@ STBIDEF void stbi_image_free(void *retval_from_stbi_load) } #ifndef STBI_NO_LINEAR -static float *stbi__ldr_to_hdr(stbi_uc *data, int x, int y, int comp); +static float *stbi__ldr_to_hdr(stbi_uc *data, int x, int y, int comp); #endif #ifndef STBI_NO_HDR -static stbi_uc *stbi__hdr_to_ldr(float *data, int x, int y, int comp); +static stbi_uc *stbi__hdr_to_ldr(float *data, int x, int y, int comp); #endif static int stbi__vertically_flip_on_load_global = 0; @@ -1119,7 +1122,7 @@ STBIDEF void stbi_set_flip_vertically_on_load(int flag_true_if_should_flip) } #ifndef STBI_THREAD_LOCAL -#define stbi__vertically_flip_on_load stbi__vertically_flip_on_load_global +#define stbi__vertically_flip_on_load stbi__vertically_flip_on_load_global #else static STBI_THREAD_LOCAL int stbi__vertically_flip_on_load_local, stbi__vertically_flip_on_load_set; @@ -1129,60 +1132,68 @@ STBIDEF void stbi_set_flip_vertically_on_load_thread(int flag_true_if_should_fli stbi__vertically_flip_on_load_set = 1; } -#define stbi__vertically_flip_on_load (stbi__vertically_flip_on_load_set \ - ? stbi__vertically_flip_on_load_local \ - : stbi__vertically_flip_on_load_global) +#define stbi__vertically_flip_on_load (stbi__vertically_flip_on_load_set \ + ? stbi__vertically_flip_on_load_local \ + : stbi__vertically_flip_on_load_global) #endif // STBI_THREAD_LOCAL static void *stbi__load_main(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri, int bpc) { - memset(ri, 0, sizeof(*ri)); // make sure it's initialized if we add new fields - ri->bits_per_channel = 8; // default is 8 so most paths don't have to be changed + memset(ri, 0, sizeof(*ri)); // make sure it's initialized if we add new fields + ri->bits_per_channel = 8; // default is 8 so most paths don't have to be changed ri->channel_order = STBI_ORDER_RGB; // all current input & output are this, but this is here so we can add BGR order ri->num_channels = 0; - // test the formats with a very explicit header first (at least a FOURCC - // or distinctive magic number first) - #ifndef STBI_NO_PNG - if (stbi__png_test(s)) return stbi__png_load(s,x,y,comp,req_comp, ri); - #endif - #ifndef STBI_NO_BMP - if (stbi__bmp_test(s)) return stbi__bmp_load(s,x,y,comp,req_comp, ri); - #endif - #ifndef STBI_NO_GIF - if (stbi__gif_test(s)) return stbi__gif_load(s,x,y,comp,req_comp, ri); - #endif - #ifndef STBI_NO_PSD - if (stbi__psd_test(s)) return stbi__psd_load(s,x,y,comp,req_comp, ri, bpc); - #else +// test the formats with a very explicit header first (at least a FOURCC +// or distinctive magic number first) +#ifndef STBI_NO_PNG + if (stbi__png_test(s)) + return stbi__png_load(s, x, y, comp, req_comp, ri); +#endif +#ifndef STBI_NO_BMP + if (stbi__bmp_test(s)) + return stbi__bmp_load(s, x, y, comp, req_comp, ri); +#endif +#ifndef STBI_NO_GIF + if (stbi__gif_test(s)) + return stbi__gif_load(s, x, y, comp, req_comp, ri); +#endif +#ifndef STBI_NO_PSD + if (stbi__psd_test(s)) + return stbi__psd_load(s, x, y, comp, req_comp, ri, bpc); +#else STBI_NOTUSED(bpc); - #endif - #ifndef STBI_NO_PIC - if (stbi__pic_test(s)) return stbi__pic_load(s,x,y,comp,req_comp, ri); - #endif +#endif +#ifndef STBI_NO_PIC + if (stbi__pic_test(s)) + return stbi__pic_load(s, x, y, comp, req_comp, ri); +#endif - // then the formats that can end up attempting to load with just 1 or 2 - // bytes matching expectations; these are prone to false positives, so - // try them later - #ifndef STBI_NO_JPEG - if (stbi__jpeg_test(s)) return stbi__jpeg_load(s,x,y,comp,req_comp, ri); - #endif - #ifndef STBI_NO_PNM - if (stbi__pnm_test(s)) return stbi__pnm_load(s,x,y,comp,req_comp, ri); - #endif +// then the formats that can end up attempting to load with just 1 or 2 +// bytes matching expectations; these are prone to false positives, so +// try them later +#ifndef STBI_NO_JPEG + if (stbi__jpeg_test(s)) + return stbi__jpeg_load(s, x, y, comp, req_comp, ri); +#endif +#ifndef STBI_NO_PNM + if (stbi__pnm_test(s)) + return stbi__pnm_load(s, x, y, comp, req_comp, ri); +#endif - #ifndef STBI_NO_HDR - if (stbi__hdr_test(s)) { - float *hdr = stbi__hdr_load(s, x,y,comp,req_comp, ri); +#ifndef STBI_NO_HDR + if (stbi__hdr_test(s)) + { + float *hdr = stbi__hdr_load(s, x, y, comp, req_comp, ri); return stbi__hdr_to_ldr(hdr, *x, *y, req_comp ? req_comp : *comp); } - #endif +#endif - #ifndef STBI_NO_TGA +#ifndef STBI_NO_TGA // test tga last because it's a crappy test! if (stbi__tga_test(s)) - return stbi__tga_load(s,x,y,comp,req_comp, ri); - #endif + return stbi__tga_load(s, x, y, comp, req_comp, ri); +#endif return stbi__errpuc("unknown image type", "Image not of any known type, or corrupt"); } @@ -1193,8 +1204,9 @@ static stbi_uc *stbi__convert_16_to_8(stbi__uint16 *orig, int w, int h, int chan int img_len = w * h * channels; stbi_uc *reduced; - reduced = (stbi_uc *) stbi__malloc(img_len); - if (reduced == NULL) return stbi__errpuc("outofmem", "Out of memory"); + reduced = (stbi_uc *)stbi__malloc(img_len); + if (reduced == NULL) + return stbi__errpuc("outofmem", "Out of memory"); for (i = 0; i < img_len; ++i) reduced[i] = (stbi_uc)((orig[i] >> 8) & 0xFF); // top half of each byte is sufficient approx of 16->8 bit scaling @@ -1209,8 +1221,9 @@ static stbi__uint16 *stbi__convert_8_to_16(stbi_uc *orig, int w, int h, int chan int img_len = w * h * channels; stbi__uint16 *enlarged; - enlarged = (stbi__uint16 *) stbi__malloc(img_len*2); - if (enlarged == NULL) return (stbi__uint16 *) stbi__errpuc("outofmem", "Out of memory"); + enlarged = (stbi__uint16 *)stbi__malloc(img_len * 2); + if (enlarged == NULL) + return (stbi__uint16 *)stbi__errpuc("outofmem", "Out of memory"); for (i = 0; i < img_len; ++i) enlarged[i] = (stbi__uint16)((orig[i] << 8) + orig[i]); // replicate to high and low byte, maps 0->0, 255->0xffff @@ -1226,12 +1239,14 @@ static void stbi__vertical_flip(void *image, int w, int h, int bytes_per_pixel) stbi_uc temp[2048]; stbi_uc *bytes = (stbi_uc *)image; - for (row = 0; row < (h>>1); row++) { - stbi_uc *row0 = bytes + row*bytes_per_row; - stbi_uc *row1 = bytes + (h - row - 1)*bytes_per_row; + for (row = 0; row < (h >> 1); row++) + { + stbi_uc *row0 = bytes + row * bytes_per_row; + stbi_uc *row1 = bytes + (h - row - 1) * bytes_per_row; // swap row0 with row1 size_t bytes_left = bytes_per_row; - while (bytes_left) { + while (bytes_left) + { size_t bytes_copy = (bytes_left < sizeof(temp)) ? bytes_left : sizeof(temp); memcpy(temp, row0, bytes_copy); memcpy(row0, row1, bytes_copy); @@ -1250,7 +1265,8 @@ static void stbi__vertical_flip_slices(void *image, int w, int h, int z, int byt int slice_size = w * h * bytes_per_pixel; stbi_uc *bytes = (stbi_uc *)image; - for (slice = 0; slice < z; ++slice) { + for (slice = 0; slice < z; ++slice) + { stbi__vertical_flip(bytes, w, h, bytes_per_pixel); bytes += slice_size; } @@ -1268,19 +1284,21 @@ static unsigned char *stbi__load_and_postprocess_8bit(stbi__context *s, int *x, // it is the responsibility of the loaders to make sure we get either 8 or 16 bit. STBI_ASSERT(ri.bits_per_channel == 8 || ri.bits_per_channel == 16); - if (ri.bits_per_channel != 8) { - result = stbi__convert_16_to_8((stbi__uint16 *) result, *x, *y, req_comp == 0 ? *comp : req_comp); + if (ri.bits_per_channel != 8) + { + result = stbi__convert_16_to_8((stbi__uint16 *)result, *x, *y, req_comp == 0 ? *comp : req_comp); ri.bits_per_channel = 8; } // @TODO: move stbi__convert_format to here - if (stbi__vertically_flip_on_load) { + if (stbi__vertically_flip_on_load) + { int channels = req_comp ? req_comp : *comp; stbi__vertical_flip(result, *x, *y, channels * sizeof(stbi_uc)); } - return (unsigned char *) result; + return (unsigned char *)result; } static stbi__uint16 *stbi__load_and_postprocess_16bit(stbi__context *s, int *x, int *y, int *comp, int req_comp) @@ -1294,26 +1312,29 @@ static stbi__uint16 *stbi__load_and_postprocess_16bit(stbi__context *s, int *x, // it is the responsibility of the loaders to make sure we get either 8 or 16 bit. STBI_ASSERT(ri.bits_per_channel == 8 || ri.bits_per_channel == 16); - if (ri.bits_per_channel != 16) { - result = stbi__convert_8_to_16((stbi_uc *) result, *x, *y, req_comp == 0 ? *comp : req_comp); + if (ri.bits_per_channel != 16) + { + result = stbi__convert_8_to_16((stbi_uc *)result, *x, *y, req_comp == 0 ? *comp : req_comp); ri.bits_per_channel = 16; } // @TODO: move stbi__convert_format16 to here // @TODO: special case RGB-to-Y (and RGBA-to-YA) for 8-bit-to-16-bit case to keep more precision - if (stbi__vertically_flip_on_load) { + if (stbi__vertically_flip_on_load) + { int channels = req_comp ? req_comp : *comp; stbi__vertical_flip(result, *x, *y, channels * sizeof(stbi__uint16)); } - return (stbi__uint16 *) result; + return (stbi__uint16 *)result; } #if !defined(STBI_NO_HDR) && !defined(STBI_NO_LINEAR) static void stbi__float_postprocess(float *result, int *x, int *y, int *comp, int req_comp) { - if (stbi__vertically_flip_on_load && result != NULL) { + if (stbi__vertically_flip_on_load && result != NULL) + { int channels = req_comp ? req_comp : *comp; stbi__vertical_flip(result, *x, *y, channels * sizeof(float)); } @@ -1328,9 +1349,9 @@ STBI_EXTERN __declspec(dllimport) int __stdcall WideCharToMultiByte(unsigned int #endif #if defined(_WIN32) && defined(STBI_WINDOWS_UTF8) -STBIDEF int stbi_convert_wchar_to_utf8(char *buffer, size_t bufferlen, const wchar_t* input) +STBIDEF int stbi_convert_wchar_to_utf8(char *buffer, size_t bufferlen, const wchar_t *input) { - return WideCharToMultiByte(65001 /* UTF8 */, 0, input, -1, buffer, (int) bufferlen, NULL, NULL); + return WideCharToMultiByte(65001 /* UTF8 */, 0, input, -1, buffer, (int)bufferlen, NULL, NULL); } #endif @@ -1340,35 +1361,35 @@ static FILE *stbi__fopen(char const *filename, char const *mode) #if defined(_WIN32) && defined(STBI_WINDOWS_UTF8) wchar_t wMode[64]; wchar_t wFilename[1024]; - if (0 == MultiByteToWideChar(65001 /* UTF8 */, 0, filename, -1, wFilename, sizeof(wFilename)/sizeof(*wFilename))) + if (0 == MultiByteToWideChar(65001 /* UTF8 */, 0, filename, -1, wFilename, sizeof(wFilename) / sizeof(*wFilename))) return 0; - if (0 == MultiByteToWideChar(65001 /* UTF8 */, 0, mode, -1, wMode, sizeof(wMode)/sizeof(*wMode))) + if (0 == MultiByteToWideChar(65001 /* UTF8 */, 0, mode, -1, wMode, sizeof(wMode) / sizeof(*wMode))) return 0; #if defined(_MSC_VER) && _MSC_VER >= 1400 - if (0 != _wfopen_s(&f, wFilename, wMode)) - f = 0; + if (0 != _wfopen_s(&f, wFilename, wMode)) + f = 0; #else f = _wfopen(wFilename, wMode); #endif #elif defined(_MSC_VER) && _MSC_VER >= 1400 if (0 != fopen_s(&f, filename, mode)) - f=0; + f = 0; #else f = fopen(filename, mode); #endif return f; } - STBIDEF stbi_uc *stbi_load(char const *filename, int *x, int *y, int *comp, int req_comp) { FILE *f = stbi__fopen(filename, "rb"); unsigned char *result; - if (!f) return stbi__errpuc("can't fopen", "Unable to open file"); - result = stbi_load_from_file(f,x,y,comp,req_comp); + if (!f) + return stbi__errpuc("can't fopen", "Unable to open file"); + result = stbi_load_from_file(f, x, y, comp, req_comp); fclose(f); return result; } @@ -1377,11 +1398,12 @@ STBIDEF stbi_uc *stbi_load_from_file(FILE *f, int *x, int *y, int *comp, int req { unsigned char *result; stbi__context s; - stbi__start_file(&s,f); - result = stbi__load_and_postprocess_8bit(&s,x,y,comp,req_comp); - if (result) { + stbi__start_file(&s, f); + result = stbi__load_and_postprocess_8bit(&s, x, y, comp, req_comp); + if (result) + { // need to 'unget' all the characters in the IO buffer - fseek(f, - (int) (s.img_buffer_end - s.img_buffer), SEEK_CUR); + fseek(f, -(int)(s.img_buffer_end - s.img_buffer), SEEK_CUR); } return result; } @@ -1390,11 +1412,12 @@ STBIDEF stbi__uint16 *stbi_load_from_file_16(FILE *f, int *x, int *y, int *comp, { stbi__uint16 *result; stbi__context s; - stbi__start_file(&s,f); - result = stbi__load_and_postprocess_16bit(&s,x,y,comp,req_comp); - if (result) { + stbi__start_file(&s, f); + result = stbi__load_and_postprocess_16bit(&s, x, y, comp, req_comp); + if (result) + { // need to 'unget' all the characters in the IO buffer - fseek(f, - (int) (s.img_buffer_end - s.img_buffer), SEEK_CUR); + fseek(f, -(int)(s.img_buffer_end - s.img_buffer), SEEK_CUR); } return result; } @@ -1403,41 +1426,41 @@ STBIDEF stbi_us *stbi_load_16(char const *filename, int *x, int *y, int *comp, i { FILE *f = stbi__fopen(filename, "rb"); stbi__uint16 *result; - if (!f) return (stbi_us *) stbi__errpuc("can't fopen", "Unable to open file"); - result = stbi_load_from_file_16(f,x,y,comp,req_comp); + if (!f) + return (stbi_us *)stbi__errpuc("can't fopen", "Unable to open file"); + result = stbi_load_from_file_16(f, x, y, comp, req_comp); fclose(f); return result; } - -#endif //!STBI_NO_STDIO +#endif //! STBI_NO_STDIO STBIDEF stbi_us *stbi_load_16_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *channels_in_file, int desired_channels) { stbi__context s; - stbi__start_mem(&s,buffer,len); - return stbi__load_and_postprocess_16bit(&s,x,y,channels_in_file,desired_channels); + stbi__start_mem(&s, buffer, len); + return stbi__load_and_postprocess_16bit(&s, x, y, channels_in_file, desired_channels); } STBIDEF stbi_us *stbi_load_16_from_callbacks(stbi_io_callbacks const *clbk, void *user, int *x, int *y, int *channels_in_file, int desired_channels) { stbi__context s; stbi__start_callbacks(&s, (stbi_io_callbacks *)clbk, user); - return stbi__load_and_postprocess_16bit(&s,x,y,channels_in_file,desired_channels); + return stbi__load_and_postprocess_16bit(&s, x, y, channels_in_file, desired_channels); } STBIDEF stbi_uc *stbi_load_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *comp, int req_comp) { stbi__context s; - stbi__start_mem(&s,buffer,len); - return stbi__load_and_postprocess_8bit(&s,x,y,comp,req_comp); + stbi__start_mem(&s, buffer, len); + return stbi__load_and_postprocess_8bit(&s, x, y, comp, req_comp); } STBIDEF stbi_uc *stbi_load_from_callbacks(stbi_io_callbacks const *clbk, void *user, int *x, int *y, int *comp, int req_comp) { stbi__context s; - stbi__start_callbacks(&s, (stbi_io_callbacks *) clbk, user); - return stbi__load_and_postprocess_8bit(&s,x,y,comp,req_comp); + stbi__start_callbacks(&s, (stbi_io_callbacks *)clbk, user); + return stbi__load_and_postprocess_8bit(&s, x, y, comp, req_comp); } #ifndef STBI_NO_GIF @@ -1445,11 +1468,12 @@ STBIDEF stbi_uc *stbi_load_gif_from_memory(stbi_uc const *buffer, int len, int * { unsigned char *result; stbi__context s; - stbi__start_mem(&s,buffer,len); + stbi__start_mem(&s, buffer, len); - result = (unsigned char*) stbi__load_gif_main(&s, delays, x, y, z, comp, req_comp); - if (stbi__vertically_flip_on_load) { - stbi__vertical_flip_slices( result, *x, *y, *z, *comp ); + result = (unsigned char *)stbi__load_gif_main(&s, delays, x, y, z, comp, req_comp); + if (stbi__vertically_flip_on_load) + { + stbi__vertical_flip_slices(result, *x, *y, *z, *comp); } return result; @@ -1460,15 +1484,16 @@ STBIDEF stbi_uc *stbi_load_gif_from_memory(stbi_uc const *buffer, int len, int * static float *stbi__loadf_main(stbi__context *s, int *x, int *y, int *comp, int req_comp) { unsigned char *data; - #ifndef STBI_NO_HDR - if (stbi__hdr_test(s)) { +#ifndef STBI_NO_HDR + if (stbi__hdr_test(s)) + { stbi__result_info ri; - float *hdr_data = stbi__hdr_load(s,x,y,comp,req_comp, &ri); + float *hdr_data = stbi__hdr_load(s, x, y, comp, req_comp, &ri); if (hdr_data) - stbi__float_postprocess(hdr_data,x,y,comp,req_comp); + stbi__float_postprocess(hdr_data, x, y, comp, req_comp); return hdr_data; } - #endif +#endif data = stbi__load_and_postprocess_8bit(s, x, y, comp, req_comp); if (data) return stbi__ldr_to_hdr(data, *x, *y, req_comp ? req_comp : *comp); @@ -1478,15 +1503,15 @@ static float *stbi__loadf_main(stbi__context *s, int *x, int *y, int *comp, int STBIDEF float *stbi_loadf_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *comp, int req_comp) { stbi__context s; - stbi__start_mem(&s,buffer,len); - return stbi__loadf_main(&s,x,y,comp,req_comp); + stbi__start_mem(&s, buffer, len); + return stbi__loadf_main(&s, x, y, comp, req_comp); } STBIDEF float *stbi_loadf_from_callbacks(stbi_io_callbacks const *clbk, void *user, int *x, int *y, int *comp, int req_comp) { stbi__context s; - stbi__start_callbacks(&s, (stbi_io_callbacks *) clbk, user); - return stbi__loadf_main(&s,x,y,comp,req_comp); + stbi__start_callbacks(&s, (stbi_io_callbacks *)clbk, user); + return stbi__loadf_main(&s, x, y, comp, req_comp); } #ifndef STBI_NO_STDIO @@ -1494,8 +1519,9 @@ STBIDEF float *stbi_loadf(char const *filename, int *x, int *y, int *comp, int r { float *result; FILE *f = stbi__fopen(filename, "rb"); - if (!f) return stbi__errpf("can't fopen", "Unable to open file"); - result = stbi_loadf_from_file(f,x,y,comp,req_comp); + if (!f) + return stbi__errpf("can't fopen", "Unable to open file"); + result = stbi_loadf_from_file(f, x, y, comp, req_comp); fclose(f); return result; } @@ -1503,8 +1529,8 @@ STBIDEF float *stbi_loadf(char const *filename, int *x, int *y, int *comp, int r STBIDEF float *stbi_loadf_from_file(FILE *f, int *x, int *y, int *comp, int req_comp) { stbi__context s; - stbi__start_file(&s,f); - return stbi__loadf_main(&s,x,y,comp,req_comp); + stbi__start_file(&s, f); + return stbi__loadf_main(&s, x, y, comp, req_comp); } #endif // !STBI_NO_STDIO @@ -1516,23 +1542,24 @@ STBIDEF float *stbi_loadf_from_file(FILE *f, int *x, int *y, int *comp, int req_ STBIDEF int stbi_is_hdr_from_memory(stbi_uc const *buffer, int len) { - #ifndef STBI_NO_HDR +#ifndef STBI_NO_HDR stbi__context s; - stbi__start_mem(&s,buffer,len); + stbi__start_mem(&s, buffer, len); return stbi__hdr_test(&s); - #else +#else STBI_NOTUSED(buffer); STBI_NOTUSED(len); return 0; - #endif +#endif } #ifndef STBI_NO_STDIO -STBIDEF int stbi_is_hdr (char const *filename) +STBIDEF int stbi_is_hdr(char const *filename) { FILE *f = stbi__fopen(filename, "rb"); - int result=0; - if (f) { + int result = 0; + if (f) + { result = stbi_is_hdr_from_file(f); fclose(f); } @@ -1541,46 +1568,45 @@ STBIDEF int stbi_is_hdr (char const *filename) STBIDEF int stbi_is_hdr_from_file(FILE *f) { - #ifndef STBI_NO_HDR +#ifndef STBI_NO_HDR long pos = ftell(f); int res; stbi__context s; - stbi__start_file(&s,f); + stbi__start_file(&s, f); res = stbi__hdr_test(&s); fseek(f, pos, SEEK_SET); return res; - #else +#else STBI_NOTUSED(f); return 0; - #endif +#endif } #endif // !STBI_NO_STDIO -STBIDEF int stbi_is_hdr_from_callbacks(stbi_io_callbacks const *clbk, void *user) +STBIDEF int stbi_is_hdr_from_callbacks(stbi_io_callbacks const *clbk, void *user) { - #ifndef STBI_NO_HDR +#ifndef STBI_NO_HDR stbi__context s; - stbi__start_callbacks(&s, (stbi_io_callbacks *) clbk, user); + stbi__start_callbacks(&s, (stbi_io_callbacks *)clbk, user); return stbi__hdr_test(&s); - #else +#else STBI_NOTUSED(clbk); STBI_NOTUSED(user); return 0; - #endif +#endif } #ifndef STBI_NO_LINEAR -static float stbi__l2h_gamma=2.2f, stbi__l2h_scale=1.0f; +static float stbi__l2h_gamma = 2.2f, stbi__l2h_scale = 1.0f; -STBIDEF void stbi_ldr_to_hdr_gamma(float gamma) { stbi__l2h_gamma = gamma; } -STBIDEF void stbi_ldr_to_hdr_scale(float scale) { stbi__l2h_scale = scale; } +STBIDEF void stbi_ldr_to_hdr_gamma(float gamma) { stbi__l2h_gamma = gamma; } +STBIDEF void stbi_ldr_to_hdr_scale(float scale) { stbi__l2h_scale = scale; } #endif -static float stbi__h2l_gamma_i=1.0f/2.2f, stbi__h2l_scale_i=1.0f; - -STBIDEF void stbi_hdr_to_ldr_gamma(float gamma) { stbi__h2l_gamma_i = 1/gamma; } -STBIDEF void stbi_hdr_to_ldr_scale(float scale) { stbi__h2l_scale_i = 1/scale; } +static float stbi__h2l_gamma_i = 1.0f / 2.2f, stbi__h2l_scale_i = 1.0f; +STBIDEF void stbi_hdr_to_ldr_gamma(float gamma) { stbi__h2l_gamma_i = 1 / gamma; } +STBIDEF void stbi_hdr_to_ldr_scale(float scale) { stbi__h2l_scale_i = 1 / scale; } ////////////////////////////////////////////////////////////////////////////// // @@ -1589,23 +1615,26 @@ STBIDEF void stbi_hdr_to_ldr_scale(float scale) { stbi__h2l_scale_i = 1/scale; enum { - STBI__SCAN_load=0, + STBI__SCAN_load = 0, STBI__SCAN_type, STBI__SCAN_header }; static void stbi__refill_buffer(stbi__context *s) { - int n = (s->io.read)(s->io_user_data,(char*)s->buffer_start,s->buflen); - s->callback_already_read += (int) (s->img_buffer - s->img_buffer_original); - if (n == 0) { + int n = (s->io.read)(s->io_user_data, (char *)s->buffer_start, s->buflen); + s->callback_already_read += (int)(s->img_buffer - s->img_buffer_original); + if (n == 0) + { // at end of file, treat same as if from memory, but need to handle case // where s->img_buffer isn't pointing to safe memory, e.g. 0-byte file s->read_from_callbacks = 0; s->img_buffer = s->buffer_start; - s->img_buffer_end = s->buffer_start+1; + s->img_buffer_end = s->buffer_start + 1; *s->img_buffer = 0; - } else { + } + else + { s->img_buffer = s->buffer_start; s->img_buffer_end = s->buffer_start + n; } @@ -1615,7 +1644,8 @@ stbi_inline static stbi_uc stbi__get8(stbi__context *s) { if (s->img_buffer < s->img_buffer_end) return *s->img_buffer++; - if (s->read_from_callbacks) { + if (s->read_from_callbacks) + { stbi__refill_buffer(s); return *s->img_buffer++; } @@ -1627,11 +1657,14 @@ stbi_inline static stbi_uc stbi__get8(stbi__context *s) #else stbi_inline static int stbi__at_eof(stbi__context *s) { - if (s->io.read) { - if (!(s->io.eof)(s->io_user_data)) return 0; + if (s->io.read) + { + if (!(s->io.eof)(s->io_user_data)) + return 0; // if feof() is true, check if buffer = end // special case: we've only got the special 0 character at the end - if (s->read_from_callbacks == 0) return 1; + if (s->read_from_callbacks == 0) + return 1; } return s->img_buffer >= s->img_buffer_end; @@ -1643,14 +1676,18 @@ stbi_inline static int stbi__at_eof(stbi__context *s) #else static void stbi__skip(stbi__context *s, int n) { - if (n == 0) return; // already there! - if (n < 0) { + if (n == 0) + return; // already there! + if (n < 0) + { s->img_buffer = s->img_buffer_end; return; } - if (s->io.read) { - int blen = (int) (s->img_buffer_end - s->img_buffer); - if (blen < n) { + if (s->io.read) + { + int blen = (int)(s->img_buffer_end - s->img_buffer); + if (blen < n) + { s->img_buffer = s->img_buffer_end; (s->io.skip)(s->io_user_data, n - blen); return; @@ -1665,25 +1702,29 @@ static void stbi__skip(stbi__context *s, int n) #else static int stbi__getn(stbi__context *s, stbi_uc *buffer, int n) { - if (s->io.read) { - int blen = (int) (s->img_buffer_end - s->img_buffer); - if (blen < n) { + if (s->io.read) + { + int blen = (int)(s->img_buffer_end - s->img_buffer); + if (blen < n) + { int res, count; memcpy(buffer, s->img_buffer, blen); - count = (s->io.read)(s->io_user_data, (char*) buffer + blen, n - blen); - res = (count == (n-blen)); + count = (s->io.read)(s->io_user_data, (char *)buffer + blen, n - blen); + res = (count == (n - blen)); s->img_buffer = s->img_buffer_end; return res; } } - if (s->img_buffer+n <= s->img_buffer_end) { + if (s->img_buffer + n <= s->img_buffer_end) + { memcpy(buffer, s->img_buffer, n); s->img_buffer += n; return 1; - } else + } + else return 0; } #endif @@ -1727,7 +1768,7 @@ static stbi__uint32 stbi__get32le(stbi__context *s) } #endif -#define STBI__BYTECAST(x) ((stbi_uc) ((x) & 255)) // truncate int to byte without warnings +#define STBI__BYTECAST(x) ((stbi_uc)((x) & 255)) // truncate int to byte without warnings #if defined(STBI_NO_JPEG) && defined(STBI_NO_PNG) && defined(STBI_NO_BMP) && defined(STBI_NO_PSD) && defined(STBI_NO_TGA) && defined(STBI_NO_GIF) && defined(STBI_NO_PIC) && defined(STBI_NO_PNM) // nothing @@ -1745,7 +1786,7 @@ static stbi__uint32 stbi__get32le(stbi__context *s) static stbi_uc stbi__compute_y(int r, int g, int b) { - return (stbi_uc) (((r*77) + (g*150) + (29*b)) >> 8); + return (stbi_uc)(((r * 77) + (g * 150) + (29 * b)) >> 8); } #endif @@ -1754,42 +1795,95 @@ static stbi_uc stbi__compute_y(int r, int g, int b) #else static unsigned char *stbi__convert_format(unsigned char *data, int img_n, int req_comp, unsigned int x, unsigned int y) { - int i,j; + int i, j; unsigned char *good; - if (req_comp == img_n) return data; + if (req_comp == img_n) + return data; STBI_ASSERT(req_comp >= 1 && req_comp <= 4); - good = (unsigned char *) stbi__malloc_mad3(req_comp, x, y, 0); - if (good == NULL) { + good = (unsigned char *)stbi__malloc_mad3(req_comp, x, y, 0); + if (good == NULL) + { STBI_FREE(data); return stbi__errpuc("outofmem", "Out of memory"); } - for (j=0; j < (int) y; ++j) { - unsigned char *src = data + j * x * img_n ; + for (j = 0; j < (int)y; ++j) + { + unsigned char *src = data + j * x * img_n; unsigned char *dest = good + j * x * req_comp; - #define STBI__COMBO(a,b) ((a)*8+(b)) - #define STBI__CASE(a,b) case STBI__COMBO(a,b): for(i=x-1; i >= 0; --i, src += a, dest += b) +#define STBI__COMBO(a, b) ((a) * 8 + (b)) +#define STBI__CASE(a, b) \ + case STBI__COMBO(a, b): \ + for (i = x - 1; i >= 0; --i, src += a, dest += b) // convert source image with img_n components to one with req_comp components; // avoid switch per pixel, so use switch per scanline and massive macros - switch (STBI__COMBO(img_n, req_comp)) { - STBI__CASE(1,2) { dest[0]=src[0]; dest[1]=255; } break; - STBI__CASE(1,3) { dest[0]=dest[1]=dest[2]=src[0]; } break; - STBI__CASE(1,4) { dest[0]=dest[1]=dest[2]=src[0]; dest[3]=255; } break; - STBI__CASE(2,1) { dest[0]=src[0]; } break; - STBI__CASE(2,3) { dest[0]=dest[1]=dest[2]=src[0]; } break; - STBI__CASE(2,4) { dest[0]=dest[1]=dest[2]=src[0]; dest[3]=src[1]; } break; - STBI__CASE(3,4) { dest[0]=src[0];dest[1]=src[1];dest[2]=src[2];dest[3]=255; } break; - STBI__CASE(3,1) { dest[0]=stbi__compute_y(src[0],src[1],src[2]); } break; - STBI__CASE(3,2) { dest[0]=stbi__compute_y(src[0],src[1],src[2]); dest[1] = 255; } break; - STBI__CASE(4,1) { dest[0]=stbi__compute_y(src[0],src[1],src[2]); } break; - STBI__CASE(4,2) { dest[0]=stbi__compute_y(src[0],src[1],src[2]); dest[1] = src[3]; } break; - STBI__CASE(4,3) { dest[0]=src[0];dest[1]=src[1];dest[2]=src[2]; } break; - default: STBI_ASSERT(0); STBI_FREE(data); STBI_FREE(good); return stbi__errpuc("unsupported", "Unsupported format conversion"); + switch (STBI__COMBO(img_n, req_comp)) + { + STBI__CASE(1, 2) + { + dest[0] = src[0]; + dest[1] = 255; + } + break; + STBI__CASE(1, 3) { dest[0] = dest[1] = dest[2] = src[0]; } + break; + STBI__CASE(1, 4) + { + dest[0] = dest[1] = dest[2] = src[0]; + dest[3] = 255; + } + break; + STBI__CASE(2, 1) { dest[0] = src[0]; } + break; + STBI__CASE(2, 3) { dest[0] = dest[1] = dest[2] = src[0]; } + break; + STBI__CASE(2, 4) + { + dest[0] = dest[1] = dest[2] = src[0]; + dest[3] = src[1]; + } + break; + STBI__CASE(3, 4) + { + dest[0] = src[0]; + dest[1] = src[1]; + dest[2] = src[2]; + dest[3] = 255; + } + break; + STBI__CASE(3, 1) { dest[0] = stbi__compute_y(src[0], src[1], src[2]); } + break; + STBI__CASE(3, 2) + { + dest[0] = stbi__compute_y(src[0], src[1], src[2]); + dest[1] = 255; + } + break; + STBI__CASE(4, 1) { dest[0] = stbi__compute_y(src[0], src[1], src[2]); } + break; + STBI__CASE(4, 2) + { + dest[0] = stbi__compute_y(src[0], src[1], src[2]); + dest[1] = src[3]; + } + break; + STBI__CASE(4, 3) + { + dest[0] = src[0]; + dest[1] = src[1]; + dest[2] = src[2]; + } + break; + default: + STBI_ASSERT(0); + STBI_FREE(data); + STBI_FREE(good); + return stbi__errpuc("unsupported", "Unsupported format conversion"); } - #undef STBI__CASE +#undef STBI__CASE } STBI_FREE(data); @@ -1802,7 +1896,7 @@ static unsigned char *stbi__convert_format(unsigned char *data, int img_n, int r #else static stbi__uint16 stbi__compute_y_16(int r, int g, int b) { - return (stbi__uint16) (((r*77) + (g*150) + (29*b)) >> 8); + return (stbi__uint16)(((r * 77) + (g * 150) + (29 * b)) >> 8); } #endif @@ -1811,42 +1905,95 @@ static stbi__uint16 stbi__compute_y_16(int r, int g, int b) #else static stbi__uint16 *stbi__convert_format16(stbi__uint16 *data, int img_n, int req_comp, unsigned int x, unsigned int y) { - int i,j; + int i, j; stbi__uint16 *good; - if (req_comp == img_n) return data; + if (req_comp == img_n) + return data; STBI_ASSERT(req_comp >= 1 && req_comp <= 4); - good = (stbi__uint16 *) stbi__malloc(req_comp * x * y * 2); - if (good == NULL) { + good = (stbi__uint16 *)stbi__malloc(req_comp * x * y * 2); + if (good == NULL) + { STBI_FREE(data); - return (stbi__uint16 *) stbi__errpuc("outofmem", "Out of memory"); + return (stbi__uint16 *)stbi__errpuc("outofmem", "Out of memory"); } - for (j=0; j < (int) y; ++j) { - stbi__uint16 *src = data + j * x * img_n ; + for (j = 0; j < (int)y; ++j) + { + stbi__uint16 *src = data + j * x * img_n; stbi__uint16 *dest = good + j * x * req_comp; - #define STBI__COMBO(a,b) ((a)*8+(b)) - #define STBI__CASE(a,b) case STBI__COMBO(a,b): for(i=x-1; i >= 0; --i, src += a, dest += b) +#define STBI__COMBO(a, b) ((a) * 8 + (b)) +#define STBI__CASE(a, b) \ + case STBI__COMBO(a, b): \ + for (i = x - 1; i >= 0; --i, src += a, dest += b) // convert source image with img_n components to one with req_comp components; // avoid switch per pixel, so use switch per scanline and massive macros - switch (STBI__COMBO(img_n, req_comp)) { - STBI__CASE(1,2) { dest[0]=src[0]; dest[1]=0xffff; } break; - STBI__CASE(1,3) { dest[0]=dest[1]=dest[2]=src[0]; } break; - STBI__CASE(1,4) { dest[0]=dest[1]=dest[2]=src[0]; dest[3]=0xffff; } break; - STBI__CASE(2,1) { dest[0]=src[0]; } break; - STBI__CASE(2,3) { dest[0]=dest[1]=dest[2]=src[0]; } break; - STBI__CASE(2,4) { dest[0]=dest[1]=dest[2]=src[0]; dest[3]=src[1]; } break; - STBI__CASE(3,4) { dest[0]=src[0];dest[1]=src[1];dest[2]=src[2];dest[3]=0xffff; } break; - STBI__CASE(3,1) { dest[0]=stbi__compute_y_16(src[0],src[1],src[2]); } break; - STBI__CASE(3,2) { dest[0]=stbi__compute_y_16(src[0],src[1],src[2]); dest[1] = 0xffff; } break; - STBI__CASE(4,1) { dest[0]=stbi__compute_y_16(src[0],src[1],src[2]); } break; - STBI__CASE(4,2) { dest[0]=stbi__compute_y_16(src[0],src[1],src[2]); dest[1] = src[3]; } break; - STBI__CASE(4,3) { dest[0]=src[0];dest[1]=src[1];dest[2]=src[2]; } break; - default: STBI_ASSERT(0); STBI_FREE(data); STBI_FREE(good); return (stbi__uint16*) stbi__errpuc("unsupported", "Unsupported format conversion"); + switch (STBI__COMBO(img_n, req_comp)) + { + STBI__CASE(1, 2) + { + dest[0] = src[0]; + dest[1] = 0xffff; + } + break; + STBI__CASE(1, 3) { dest[0] = dest[1] = dest[2] = src[0]; } + break; + STBI__CASE(1, 4) + { + dest[0] = dest[1] = dest[2] = src[0]; + dest[3] = 0xffff; + } + break; + STBI__CASE(2, 1) { dest[0] = src[0]; } + break; + STBI__CASE(2, 3) { dest[0] = dest[1] = dest[2] = src[0]; } + break; + STBI__CASE(2, 4) + { + dest[0] = dest[1] = dest[2] = src[0]; + dest[3] = src[1]; + } + break; + STBI__CASE(3, 4) + { + dest[0] = src[0]; + dest[1] = src[1]; + dest[2] = src[2]; + dest[3] = 0xffff; + } + break; + STBI__CASE(3, 1) { dest[0] = stbi__compute_y_16(src[0], src[1], src[2]); } + break; + STBI__CASE(3, 2) + { + dest[0] = stbi__compute_y_16(src[0], src[1], src[2]); + dest[1] = 0xffff; + } + break; + STBI__CASE(4, 1) { dest[0] = stbi__compute_y_16(src[0], src[1], src[2]); } + break; + STBI__CASE(4, 2) + { + dest[0] = stbi__compute_y_16(src[0], src[1], src[2]); + dest[1] = src[3]; + } + break; + STBI__CASE(4, 3) + { + dest[0] = src[0]; + dest[1] = src[1]; + dest[2] = src[2]; + } + break; + default: + STBI_ASSERT(0); + STBI_FREE(data); + STBI_FREE(good); + return (stbi__uint16 *)stbi__errpuc("unsupported", "Unsupported format conversion"); } - #undef STBI__CASE +#undef STBI__CASE } STBI_FREE(data); @@ -1855,23 +2002,35 @@ static stbi__uint16 *stbi__convert_format16(stbi__uint16 *data, int img_n, int r #endif #ifndef STBI_NO_LINEAR -static float *stbi__ldr_to_hdr(stbi_uc *data, int x, int y, int comp) +static float *stbi__ldr_to_hdr(stbi_uc *data, int x, int y, int comp) { - int i,k,n; + int i, k, n; float *output; - if (!data) return NULL; - output = (float *) stbi__malloc_mad4(x, y, comp, sizeof(float), 0); - if (output == NULL) { STBI_FREE(data); return stbi__errpf("outofmem", "Out of memory"); } + if (!data) + return NULL; + output = (float *)stbi__malloc_mad4(x, y, comp, sizeof(float), 0); + if (output == NULL) + { + STBI_FREE(data); + return stbi__errpf("outofmem", "Out of memory"); + } // compute number of non-alpha components - if (comp & 1) n = comp; else n = comp-1; - for (i=0; i < x*y; ++i) { - for (k=0; k < n; ++k) { - output[i*comp + k] = (float) (pow(data[i*comp+k]/255.0f, stbi__l2h_gamma) * stbi__l2h_scale); + if (comp & 1) + n = comp; + else + n = comp - 1; + for (i = 0; i < x * y; ++i) + { + for (k = 0; k < n; ++k) + { + output[i * comp + k] = (float)(pow(data[i * comp + k] / 255.0f, stbi__l2h_gamma) * stbi__l2h_scale); } } - if (n < comp) { - for (i=0; i < x*y; ++i) { - output[i*comp + n] = data[i*comp + n]/255.0f; + if (n < comp) + { + for (i = 0; i < x * y; ++i) + { + output[i * comp + n] = data[i * comp + n] / 255.0f; } } STBI_FREE(data); @@ -1880,28 +2039,43 @@ static float *stbi__ldr_to_hdr(stbi_uc *data, int x, int y, int comp) #endif #ifndef STBI_NO_HDR -#define stbi__float2int(x) ((int) (x)) -static stbi_uc *stbi__hdr_to_ldr(float *data, int x, int y, int comp) +#define stbi__float2int(x) ((int)(x)) +static stbi_uc *stbi__hdr_to_ldr(float *data, int x, int y, int comp) { - int i,k,n; + int i, k, n; stbi_uc *output; - if (!data) return NULL; - output = (stbi_uc *) stbi__malloc_mad3(x, y, comp, 0); - if (output == NULL) { STBI_FREE(data); return stbi__errpuc("outofmem", "Out of memory"); } + if (!data) + return NULL; + output = (stbi_uc *)stbi__malloc_mad3(x, y, comp, 0); + if (output == NULL) + { + STBI_FREE(data); + return stbi__errpuc("outofmem", "Out of memory"); + } // compute number of non-alpha components - if (comp & 1) n = comp; else n = comp-1; - for (i=0; i < x*y; ++i) { - for (k=0; k < n; ++k) { - float z = (float) pow(data[i*comp+k]*stbi__h2l_scale_i, stbi__h2l_gamma_i) * 255 + 0.5f; - if (z < 0) z = 0; - if (z > 255) z = 255; - output[i*comp + k] = (stbi_uc) stbi__float2int(z); + if (comp & 1) + n = comp; + else + n = comp - 1; + for (i = 0; i < x * y; ++i) + { + for (k = 0; k < n; ++k) + { + float z = (float)pow(data[i * comp + k] * stbi__h2l_scale_i, stbi__h2l_gamma_i) * 255 + 0.5f; + if (z < 0) + z = 0; + if (z > 255) + z = 255; + output[i * comp + k] = (stbi_uc)stbi__float2int(z); } - if (k < comp) { - float z = data[i*comp+k] * 255 + 0.5f; - if (z < 0) z = 0; - if (z > 255) z = 255; - output[i*comp + k] = (stbi_uc) stbi__float2int(z); + if (k < comp) + { + float z = data[i * comp + k] * 255 + 0.5f; + if (z < 0) + z = 0; + if (z > 255) + z = 255; + output[i * comp + k] = (stbi_uc)stbi__float2int(z); } } STBI_FREE(data); @@ -1933,17 +2107,17 @@ static stbi_uc *stbi__hdr_to_ldr(float *data, int x, int y, int comp) #ifndef STBI_NO_JPEG // huffman decoding acceleration -#define FAST_BITS 9 // larger handles more cases; smaller stomps less cache +#define FAST_BITS 9 // larger handles more cases; smaller stomps less cache typedef struct { - stbi_uc fast[1 << FAST_BITS]; + stbi_uc fast[1 << FAST_BITS]; // weirdly, repacking this into AoS is a 10% speed loss, instead of a win stbi__uint16 code[256]; - stbi_uc values[256]; - stbi_uc size[257]; + stbi_uc values[256]; + stbi_uc size[257]; unsigned int maxcode[18]; - int delta[17]; // old 'firstsymbol' - old 'firstcode' + int delta[17]; // old 'firstsymbol' - old 'firstcode' } stbi__huffman; typedef struct @@ -1954,47 +2128,47 @@ typedef struct stbi__uint16 dequant[4][64]; stbi__int16 fast_ac[4][1 << FAST_BITS]; -// sizes for components, interleaved MCUs + // sizes for components, interleaved MCUs int img_h_max, img_v_max; int img_mcu_x, img_mcu_y; int img_mcu_w, img_mcu_h; -// definition of jpeg image component + // definition of jpeg image component struct { int id; - int h,v; + int h, v; int tq; - int hd,ha; + int hd, ha; int dc_pred; - int x,y,w2,h2; + int x, y, w2, h2; stbi_uc *data; void *raw_data, *raw_coeff; stbi_uc *linebuf; - short *coeff; // progressive only - int coeff_w, coeff_h; // number of 8x8 coefficient blocks + short *coeff; // progressive only + int coeff_w, coeff_h; // number of 8x8 coefficient blocks } img_comp[4]; - stbi__uint32 code_buffer; // jpeg entropy-coded buffer - int code_bits; // number of valid bits - unsigned char marker; // marker seen while filling entropy buffer - int nomore; // flag if we saw a marker so must stop + stbi__uint32 code_buffer; // jpeg entropy-coded buffer + int code_bits; // number of valid bits + unsigned char marker; // marker seen while filling entropy buffer + int nomore; // flag if we saw a marker so must stop - int progressive; - int spec_start; - int spec_end; - int succ_high; - int succ_low; - int eob_run; - int jfif; - int app14_color_transform; // Adobe APP14 tag - int rgb; + int progressive; + int spec_start; + int spec_end; + int succ_high; + int succ_low; + int eob_run; + int jfif; + int app14_color_transform; // Adobe APP14 tag + int rgb; int scan_n, order[4]; int restart_interval, todo; -// kernels + // kernels void (*idct_block_kernel)(stbi_uc *out, int out_stride, short data[64]); void (*YCbCr_to_RGB_kernel)(stbi_uc *out, const stbi_uc *y, const stbi_uc *pcb, const stbi_uc *pcr, int count, int step); stbi_uc *(*resample_row_hv_2_kernel)(stbi_uc *out, stbi_uc *in_near, stbi_uc *in_far, int w, int hs); @@ -2002,13 +2176,16 @@ typedef struct static int stbi__build_huffman(stbi__huffman *h, int *count) { - int i,j,k=0; + int i, j, k = 0; unsigned int code; // build size list for each symbol (from JPEG spec) - for (i=0; i < 16; ++i) { - for (j=0; j < count[i]; ++j) { - h->size[k++] = (stbi_uc) (i+1); - if(k >= 257) return stbi__err("bad size list","Corrupt JPEG"); + for (i = 0; i < 16; ++i) + { + for (j = 0; j < count[i]; ++j) + { + h->size[k++] = (stbi_uc)(i + 1); + if (k >= 257) + return stbi__err("bad size list", "Corrupt JPEG"); } } h->size[k] = 0; @@ -2016,29 +2193,35 @@ static int stbi__build_huffman(stbi__huffman *h, int *count) // compute actual symbols (from jpeg spec) code = 0; k = 0; - for(j=1; j <= 16; ++j) { + for (j = 1; j <= 16; ++j) + { // compute delta to add to code to compute symbol id h->delta[j] = k - code; - if (h->size[k] == j) { + if (h->size[k] == j) + { while (h->size[k] == j) - h->code[k++] = (stbi__uint16) (code++); - if (code-1 >= (1u << j)) return stbi__err("bad code lengths","Corrupt JPEG"); + h->code[k++] = (stbi__uint16)(code++); + if (code - 1 >= (1u << j)) + return stbi__err("bad code lengths", "Corrupt JPEG"); } // compute largest code + 1 for this size, preshifted as needed later - h->maxcode[j] = code << (16-j); + h->maxcode[j] = code << (16 - j); code <<= 1; } h->maxcode[j] = 0xffffffff; // build non-spec acceleration table; 255 is flag for not-accelerated memset(h->fast, 255, 1 << FAST_BITS); - for (i=0; i < k; ++i) { + for (i = 0; i < k; ++i) + { int s = h->size[i]; - if (s <= FAST_BITS) { - int c = h->code[i] << (FAST_BITS-s); - int m = 1 << (FAST_BITS-s); - for (j=0; j < m; ++j) { - h->fast[c+j] = (stbi_uc) i; + if (s <= FAST_BITS) + { + int c = h->code[i] << (FAST_BITS - s); + int m = 1 << (FAST_BITS - s); + for (j = 0; j < m; ++j) + { + h->fast[c + j] = (stbi_uc)i; } } } @@ -2050,23 +2233,27 @@ static int stbi__build_huffman(stbi__huffman *h, int *count) static void stbi__build_fast_ac(stbi__int16 *fast_ac, stbi__huffman *h) { int i; - for (i=0; i < (1 << FAST_BITS); ++i) { + for (i = 0; i < (1 << FAST_BITS); ++i) + { stbi_uc fast = h->fast[i]; fast_ac[i] = 0; - if (fast < 255) { + if (fast < 255) + { int rs = h->values[fast]; int run = (rs >> 4) & 15; int magbits = rs & 15; int len = h->size[fast]; - if (magbits && len + magbits <= FAST_BITS) { + if (magbits && len + magbits <= FAST_BITS) + { // magnitude code followed by receive_extend code int k = ((i << len) & ((1 << FAST_BITS) - 1)) >> (FAST_BITS - magbits); int m = 1 << (magbits - 1); - if (k < m) k += (~0U << magbits) + 1; + if (k < m) + k += (~0U << magbits) + 1; // if the result is small enough, we can fit it in fast_ac table if (k >= -128 && k <= 127) - fast_ac[i] = (stbi__int16) ((k * 256) + (run * 16) + (len + magbits)); + fast_ac[i] = (stbi__int16)((k * 256) + (run * 16) + (len + magbits)); } } } @@ -2074,13 +2261,17 @@ static void stbi__build_fast_ac(stbi__int16 *fast_ac, stbi__huffman *h) static void stbi__grow_buffer_unsafe(stbi__jpeg *j) { - do { + do + { unsigned int b = j->nomore ? 0 : stbi__get8(j->s); - if (b == 0xff) { + if (b == 0xff) + { int c = stbi__get8(j->s); - while (c == 0xff) c = stbi__get8(j->s); // consume fill bytes - if (c != 0) { - j->marker = (unsigned char) c; + while (c == 0xff) + c = stbi__get8(j->s); // consume fill bytes + if (c != 0) + { + j->marker = (unsigned char)c; j->nomore = 1; return; } @@ -2091,21 +2282,23 @@ static void stbi__grow_buffer_unsafe(stbi__jpeg *j) } // (1 << n) - 1 -static const stbi__uint32 stbi__bmask[17]={0,1,3,7,15,31,63,127,255,511,1023,2047,4095,8191,16383,32767,65535}; +static const stbi__uint32 stbi__bmask[17] = {0, 1, 3, 7, 15, 31, 63, 127, 255, 511, 1023, 2047, 4095, 8191, 16383, 32767, 65535}; // decode a jpeg huffman value from the bitstream stbi_inline static int stbi__jpeg_huff_decode(stbi__jpeg *j, stbi__huffman *h) { unsigned int temp; - int c,k; + int c, k; - if (j->code_bits < 16) stbi__grow_buffer_unsafe(j); + if (j->code_bits < 16) + stbi__grow_buffer_unsafe(j); // look at the top FAST_BITS and determine what symbol ID it is, // if the code is <= FAST_BITS - c = (j->code_buffer >> (32 - FAST_BITS)) & ((1 << FAST_BITS)-1); + c = (j->code_buffer >> (32 - FAST_BITS)) & ((1 << FAST_BITS) - 1); k = h->fast[c]; - if (k < 255) { + if (k < 255) + { int s = h->size[k]; if (s > j->code_bits) return -1; @@ -2121,10 +2314,11 @@ stbi_inline static int stbi__jpeg_huff_decode(stbi__jpeg *j, stbi__huffman *h) // wants to be compared against something shifted to have 16; // that way we don't need to shift inside the loop. temp = j->code_buffer >> 16; - for (k=FAST_BITS+1 ; ; ++k) + for (k = FAST_BITS + 1;; ++k) if (temp < h->maxcode[k]) break; - if (k == 17) { + if (k == 17) + { // error! code not found j->code_bits -= 16; return -1; @@ -2135,8 +2329,8 @@ stbi_inline static int stbi__jpeg_huff_decode(stbi__jpeg *j, stbi__huffman *h) // convert the huffman code to the symbol id c = ((j->code_buffer >> (32 - k)) & stbi__bmask[k]) + h->delta[k]; - if(c < 0 || c >= 256) // symbol id out of bounds! - return -1; + if (c < 0 || c >= 256) // symbol id out of bounds! + return -1; STBI_ASSERT((((j->code_buffer) >> (32 - h->size[c])) & stbi__bmask[h->size[c]]) == h->code[c]); // convert the id to a symbol @@ -2146,7 +2340,7 @@ stbi_inline static int stbi__jpeg_huff_decode(stbi__jpeg *j, stbi__huffman *h) } // bias[n] = (-1<code_bits < n) stbi__grow_buffer_unsafe(j); - if (j->code_bits < n) return 0; // ran out of bits from stream, return 0s intead of continuing + if (j->code_bits < n) + stbi__grow_buffer_unsafe(j); + if (j->code_bits < n) + return 0; // ran out of bits from stream, return 0s intead of continuing sgn = j->code_buffer >> 31; // sign bit always in MSB; 0 if MSB clear (positive), 1 if MSB set (negative) k = stbi_lrot(j->code_buffer, n); @@ -2169,8 +2365,10 @@ stbi_inline static int stbi__extend_receive(stbi__jpeg *j, int n) stbi_inline static int stbi__jpeg_get_bits(stbi__jpeg *j, int n) { unsigned int k; - if (j->code_bits < n) stbi__grow_buffer_unsafe(j); - if (j->code_bits < n) return 0; // ran out of bits from stream, return 0s intead of continuing + if (j->code_bits < n) + stbi__grow_buffer_unsafe(j); + if (j->code_bits < n) + return 0; // ran out of bits from stream, return 0s intead of continuing k = stbi_lrot(j->code_buffer, n); j->code_buffer = k & ~stbi__bmask[n]; k &= stbi__bmask[n]; @@ -2181,8 +2379,10 @@ stbi_inline static int stbi__jpeg_get_bits(stbi__jpeg *j, int n) stbi_inline static int stbi__jpeg_get_bit(stbi__jpeg *j) { unsigned int k; - if (j->code_bits < 1) stbi__grow_buffer_unsafe(j); - if (j->code_bits < 1) return 0; // ran out of bits from stream, return 0s intead of continuing + if (j->code_bits < 1) + stbi__grow_buffer_unsafe(j); + if (j->code_bits < 1) + return 0; // ran out of bits from stream, return 0s intead of continuing k = j->code_buffer; j->code_buffer <<= 1; --j->code_bits; @@ -2191,71 +2391,85 @@ stbi_inline static int stbi__jpeg_get_bit(stbi__jpeg *j) // given a value that's at position X in the zigzag stream, // where does it appear in the 8x8 matrix coded as row-major? -static const stbi_uc stbi__jpeg_dezigzag[64+15] = -{ - 0, 1, 8, 16, 9, 2, 3, 10, - 17, 24, 32, 25, 18, 11, 4, 5, - 12, 19, 26, 33, 40, 48, 41, 34, - 27, 20, 13, 6, 7, 14, 21, 28, - 35, 42, 49, 56, 57, 50, 43, 36, - 29, 22, 15, 23, 30, 37, 44, 51, - 58, 59, 52, 45, 38, 31, 39, 46, - 53, 60, 61, 54, 47, 55, 62, 63, - // let corrupt input sample past end - 63, 63, 63, 63, 63, 63, 63, 63, - 63, 63, 63, 63, 63, 63, 63 -}; +static const stbi_uc stbi__jpeg_dezigzag[64 + 15] = + { + 0, 1, 8, 16, 9, 2, 3, 10, + 17, 24, 32, 25, 18, 11, 4, 5, + 12, 19, 26, 33, 40, 48, 41, 34, + 27, 20, 13, 6, 7, 14, 21, 28, + 35, 42, 49, 56, 57, 50, 43, 36, + 29, 22, 15, 23, 30, 37, 44, 51, + 58, 59, 52, 45, 38, 31, 39, 46, + 53, 60, 61, 54, 47, 55, 62, 63, + // let corrupt input sample past end + 63, 63, 63, 63, 63, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 63}; // decode one 64-entry block-- static int stbi__jpeg_decode_block(stbi__jpeg *j, short data[64], stbi__huffman *hdc, stbi__huffman *hac, stbi__int16 *fac, int b, stbi__uint16 *dequant) { - int diff,dc,k; + int diff, dc, k; int t; - if (j->code_bits < 16) stbi__grow_buffer_unsafe(j); + if (j->code_bits < 16) + stbi__grow_buffer_unsafe(j); t = stbi__jpeg_huff_decode(j, hdc); - if (t < 0 || t > 15) return stbi__err("bad huffman code","Corrupt JPEG"); + if (t < 0 || t > 15) + return stbi__err("bad huffman code", "Corrupt JPEG"); // 0 all the ac values now so we can do it 32-bits at a time - memset(data,0,64*sizeof(data[0])); + memset(data, 0, 64 * sizeof(data[0])); diff = t ? stbi__extend_receive(j, t) : 0; - if (!stbi__addints_valid(j->img_comp[b].dc_pred, diff)) return stbi__err("bad delta","Corrupt JPEG"); + if (!stbi__addints_valid(j->img_comp[b].dc_pred, diff)) + return stbi__err("bad delta", "Corrupt JPEG"); dc = j->img_comp[b].dc_pred + diff; j->img_comp[b].dc_pred = dc; - if (!stbi__mul2shorts_valid(dc, dequant[0])) return stbi__err("can't merge dc and ac", "Corrupt JPEG"); - data[0] = (short) (dc * dequant[0]); + if (!stbi__mul2shorts_valid(dc, dequant[0])) + return stbi__err("can't merge dc and ac", "Corrupt JPEG"); + data[0] = (short)(dc * dequant[0]); // decode AC components, see JPEG spec k = 1; - do { + do + { unsigned int zig; - int c,r,s; - if (j->code_bits < 16) stbi__grow_buffer_unsafe(j); - c = (j->code_buffer >> (32 - FAST_BITS)) & ((1 << FAST_BITS)-1); + int c, r, s; + if (j->code_bits < 16) + stbi__grow_buffer_unsafe(j); + c = (j->code_buffer >> (32 - FAST_BITS)) & ((1 << FAST_BITS) - 1); r = fac[c]; - if (r) { // fast-AC path + if (r) + { // fast-AC path k += (r >> 4) & 15; // run - s = r & 15; // combined length - if (s > j->code_bits) return stbi__err("bad huffman code", "Combined length longer than code bits available"); + s = r & 15; // combined length + if (s > j->code_bits) + return stbi__err("bad huffman code", "Combined length longer than code bits available"); j->code_buffer <<= s; j->code_bits -= s; // decode into unzigzag'd location zig = stbi__jpeg_dezigzag[k++]; - data[zig] = (short) ((r >> 8) * dequant[zig]); - } else { + data[zig] = (short)((r >> 8) * dequant[zig]); + } + else + { int rs = stbi__jpeg_huff_decode(j, hac); - if (rs < 0) return stbi__err("bad huffman code","Corrupt JPEG"); + if (rs < 0) + return stbi__err("bad huffman code", "Corrupt JPEG"); s = rs & 15; r = rs >> 4; - if (s == 0) { - if (rs != 0xf0) break; // end block + if (s == 0) + { + if (rs != 0xf0) + break; // end block k += 16; - } else { + } + else + { k += r; // decode into unzigzag'd location zig = stbi__jpeg_dezigzag[k++]; - data[zig] = (short) (stbi__extend_receive(j,s) * dequant[zig]); + data[zig] = (short)(stbi__extend_receive(j, s) * dequant[zig]); } } } while (k < 64); @@ -2264,28 +2478,36 @@ static int stbi__jpeg_decode_block(stbi__jpeg *j, short data[64], stbi__huffman static int stbi__jpeg_decode_block_prog_dc(stbi__jpeg *j, short data[64], stbi__huffman *hdc, int b) { - int diff,dc; + int diff, dc; int t; - if (j->spec_end != 0) return stbi__err("can't merge dc and ac", "Corrupt JPEG"); + if (j->spec_end != 0) + return stbi__err("can't merge dc and ac", "Corrupt JPEG"); - if (j->code_bits < 16) stbi__grow_buffer_unsafe(j); + if (j->code_bits < 16) + stbi__grow_buffer_unsafe(j); - if (j->succ_high == 0) { + if (j->succ_high == 0) + { // first scan for DC coefficient, must be first - memset(data,0,64*sizeof(data[0])); // 0 all the ac values now + memset(data, 0, 64 * sizeof(data[0])); // 0 all the ac values now t = stbi__jpeg_huff_decode(j, hdc); - if (t < 0 || t > 15) return stbi__err("can't merge dc and ac", "Corrupt JPEG"); + if (t < 0 || t > 15) + return stbi__err("can't merge dc and ac", "Corrupt JPEG"); diff = t ? stbi__extend_receive(j, t) : 0; - if (!stbi__addints_valid(j->img_comp[b].dc_pred, diff)) return stbi__err("bad delta", "Corrupt JPEG"); + if (!stbi__addints_valid(j->img_comp[b].dc_pred, diff)) + return stbi__err("bad delta", "Corrupt JPEG"); dc = j->img_comp[b].dc_pred + diff; j->img_comp[b].dc_pred = dc; - if (!stbi__mul2shorts_valid(dc, 1 << j->succ_low)) return stbi__err("can't merge dc and ac", "Corrupt JPEG"); - data[0] = (short) (dc * (1 << j->succ_low)); - } else { + if (!stbi__mul2shorts_valid(dc, 1 << j->succ_low)) + return stbi__err("can't merge dc and ac", "Corrupt JPEG"); + data[0] = (short)(dc * (1 << j->succ_low)); + } + else + { // refinement scan for DC coefficient if (stbi__jpeg_get_bit(j)) - data[0] += (short) (1 << j->succ_low); + data[0] += (short)(1 << j->succ_low); } return 1; } @@ -2295,38 +2517,50 @@ static int stbi__jpeg_decode_block_prog_dc(stbi__jpeg *j, short data[64], stbi__ static int stbi__jpeg_decode_block_prog_ac(stbi__jpeg *j, short data[64], stbi__huffman *hac, stbi__int16 *fac) { int k; - if (j->spec_start == 0) return stbi__err("can't merge dc and ac", "Corrupt JPEG"); + if (j->spec_start == 0) + return stbi__err("can't merge dc and ac", "Corrupt JPEG"); - if (j->succ_high == 0) { + if (j->succ_high == 0) + { int shift = j->succ_low; - if (j->eob_run) { + if (j->eob_run) + { --j->eob_run; return 1; } k = j->spec_start; - do { + do + { unsigned int zig; - int c,r,s; - if (j->code_bits < 16) stbi__grow_buffer_unsafe(j); - c = (j->code_buffer >> (32 - FAST_BITS)) & ((1 << FAST_BITS)-1); + int c, r, s; + if (j->code_bits < 16) + stbi__grow_buffer_unsafe(j); + c = (j->code_buffer >> (32 - FAST_BITS)) & ((1 << FAST_BITS) - 1); r = fac[c]; - if (r) { // fast-AC path + if (r) + { // fast-AC path k += (r >> 4) & 15; // run - s = r & 15; // combined length - if (s > j->code_bits) return stbi__err("bad huffman code", "Combined length longer than code bits available"); + s = r & 15; // combined length + if (s > j->code_bits) + return stbi__err("bad huffman code", "Combined length longer than code bits available"); j->code_buffer <<= s; j->code_bits -= s; zig = stbi__jpeg_dezigzag[k++]; - data[zig] = (short) ((r >> 8) * (1 << shift)); - } else { + data[zig] = (short)((r >> 8) * (1 << shift)); + } + else + { int rs = stbi__jpeg_huff_decode(j, hac); - if (rs < 0) return stbi__err("bad huffman code","Corrupt JPEG"); + if (rs < 0) + return stbi__err("bad huffman code", "Corrupt JPEG"); s = rs & 15; r = rs >> 4; - if (s == 0) { - if (r < 15) { + if (s == 0) + { + if (r < 15) + { j->eob_run = (1 << r); if (r) j->eob_run += stbi__jpeg_get_bits(j, r); @@ -2334,52 +2568,70 @@ static int stbi__jpeg_decode_block_prog_ac(stbi__jpeg *j, short data[64], stbi__ break; } k += 16; - } else { + } + else + { k += r; zig = stbi__jpeg_dezigzag[k++]; - data[zig] = (short) (stbi__extend_receive(j,s) * (1 << shift)); + data[zig] = (short)(stbi__extend_receive(j, s) * (1 << shift)); } } } while (k <= j->spec_end); - } else { + } + else + { // refinement scan for these AC coefficients - short bit = (short) (1 << j->succ_low); + short bit = (short)(1 << j->succ_low); - if (j->eob_run) { + if (j->eob_run) + { --j->eob_run; - for (k = j->spec_start; k <= j->spec_end; ++k) { + for (k = j->spec_start; k <= j->spec_end; ++k) + { short *p = &data[stbi__jpeg_dezigzag[k]]; if (*p != 0) if (stbi__jpeg_get_bit(j)) - if ((*p & bit)==0) { + if ((*p & bit) == 0) + { if (*p > 0) *p += bit; else *p -= bit; } } - } else { + } + else + { k = j->spec_start; - do { - int r,s; + do + { + int r, s; int rs = stbi__jpeg_huff_decode(j, hac); // @OPTIMIZE see if we can use the fast path here, advance-by-r is so slow, eh - if (rs < 0) return stbi__err("bad huffman code","Corrupt JPEG"); + if (rs < 0) + return stbi__err("bad huffman code", "Corrupt JPEG"); s = rs & 15; r = rs >> 4; - if (s == 0) { - if (r < 15) { + if (s == 0) + { + if (r < 15) + { j->eob_run = (1 << r) - 1; if (r) j->eob_run += stbi__jpeg_get_bits(j, r); r = 64; // force end of block - } else { + } + else + { // r=15 s=0 should write 16 0s, so we just do // a run of 15 0s and then write s (which is 0), // so we don't have to do anything special here } - } else { - if (s != 1) return stbi__err("bad huffman code", "Corrupt JPEG"); + } + else + { + if (s != 1) + return stbi__err("bad huffman code", "Corrupt JPEG"); // sign bit if (stbi__jpeg_get_bit(j)) s = bit; @@ -2388,19 +2640,25 @@ static int stbi__jpeg_decode_block_prog_ac(stbi__jpeg *j, short data[64], stbi__ } // advance by r - while (k <= j->spec_end) { + while (k <= j->spec_end) + { short *p = &data[stbi__jpeg_dezigzag[k++]]; - if (*p != 0) { + if (*p != 0) + { if (stbi__jpeg_get_bit(j)) - if ((*p & bit)==0) { + if ((*p & bit) == 0) + { if (*p > 0) *p += bit; else *p -= bit; } - } else { - if (r == 0) { - *p = (short) s; + } + else + { + if (r == 0) + { + *p = (short)s; break; } --r; @@ -2416,110 +2674,120 @@ static int stbi__jpeg_decode_block_prog_ac(stbi__jpeg *j, short data[64], stbi__ stbi_inline static stbi_uc stbi__clamp(int x) { // trick to use a single test to catch both cases - if ((unsigned int) x > 255) { - if (x < 0) return 0; - if (x > 255) return 255; + if ((unsigned int)x > 255) + { + if (x < 0) + return 0; + if (x > 255) + return 255; } - return (stbi_uc) x; + return (stbi_uc)x; } -#define stbi__f2f(x) ((int) (((x) * 4096 + 0.5))) -#define stbi__fsh(x) ((x) * 4096) +#define stbi__f2f(x) ((int)(((x) * 4096 + 0.5))) +#define stbi__fsh(x) ((x) * 4096) // derived from jidctint -- DCT_ISLOW -#define STBI__IDCT_1D(s0,s1,s2,s3,s4,s5,s6,s7) \ - int t0,t1,t2,t3,p1,p2,p3,p4,p5,x0,x1,x2,x3; \ - p2 = s2; \ - p3 = s6; \ - p1 = (p2+p3) * stbi__f2f(0.5411961f); \ - t2 = p1 + p3*stbi__f2f(-1.847759065f); \ - t3 = p1 + p2*stbi__f2f( 0.765366865f); \ - p2 = s0; \ - p3 = s4; \ - t0 = stbi__fsh(p2+p3); \ - t1 = stbi__fsh(p2-p3); \ - x0 = t0+t3; \ - x3 = t0-t3; \ - x1 = t1+t2; \ - x2 = t1-t2; \ - t0 = s7; \ - t1 = s5; \ - t2 = s3; \ - t3 = s1; \ - p3 = t0+t2; \ - p4 = t1+t3; \ - p1 = t0+t3; \ - p2 = t1+t2; \ - p5 = (p3+p4)*stbi__f2f( 1.175875602f); \ - t0 = t0*stbi__f2f( 0.298631336f); \ - t1 = t1*stbi__f2f( 2.053119869f); \ - t2 = t2*stbi__f2f( 3.072711026f); \ - t3 = t3*stbi__f2f( 1.501321110f); \ - p1 = p5 + p1*stbi__f2f(-0.899976223f); \ - p2 = p5 + p2*stbi__f2f(-2.562915447f); \ - p3 = p3*stbi__f2f(-1.961570560f); \ - p4 = p4*stbi__f2f(-0.390180644f); \ - t3 += p1+p4; \ - t2 += p2+p3; \ - t1 += p2+p4; \ - t0 += p1+p3; +#define STBI__IDCT_1D(s0, s1, s2, s3, s4, s5, s6, s7) \ + int t0, t1, t2, t3, p1, p2, p3, p4, p5, x0, x1, x2, x3; \ + p2 = s2; \ + p3 = s6; \ + p1 = (p2 + p3) * stbi__f2f(0.5411961f); \ + t2 = p1 + p3 * stbi__f2f(-1.847759065f); \ + t3 = p1 + p2 * stbi__f2f(0.765366865f); \ + p2 = s0; \ + p3 = s4; \ + t0 = stbi__fsh(p2 + p3); \ + t1 = stbi__fsh(p2 - p3); \ + x0 = t0 + t3; \ + x3 = t0 - t3; \ + x1 = t1 + t2; \ + x2 = t1 - t2; \ + t0 = s7; \ + t1 = s5; \ + t2 = s3; \ + t3 = s1; \ + p3 = t0 + t2; \ + p4 = t1 + t3; \ + p1 = t0 + t3; \ + p2 = t1 + t2; \ + p5 = (p3 + p4) * stbi__f2f(1.175875602f); \ + t0 = t0 * stbi__f2f(0.298631336f); \ + t1 = t1 * stbi__f2f(2.053119869f); \ + t2 = t2 * stbi__f2f(3.072711026f); \ + t3 = t3 * stbi__f2f(1.501321110f); \ + p1 = p5 + p1 * stbi__f2f(-0.899976223f); \ + p2 = p5 + p2 * stbi__f2f(-2.562915447f); \ + p3 = p3 * stbi__f2f(-1.961570560f); \ + p4 = p4 * stbi__f2f(-0.390180644f); \ + t3 += p1 + p4; \ + t2 += p2 + p3; \ + t1 += p2 + p4; \ + t0 += p1 + p3; static void stbi__idct_block(stbi_uc *out, int out_stride, short data[64]) { - int i,val[64],*v=val; + int i, val[64], *v = val; stbi_uc *o; short *d = data; // columns - for (i=0; i < 8; ++i,++d, ++v) { + for (i = 0; i < 8; ++i, ++d, ++v) + { // if all zeroes, shortcut -- this avoids dequantizing 0s and IDCTing - if (d[ 8]==0 && d[16]==0 && d[24]==0 && d[32]==0 - && d[40]==0 && d[48]==0 && d[56]==0) { + if (d[8] == 0 && d[16] == 0 && d[24] == 0 && d[32] == 0 && d[40] == 0 && d[48] == 0 && d[56] == 0) + { // no shortcut 0 seconds // (1|2|3|4|5|6|7)==0 0 seconds // all separate -0.047 seconds // 1 && 2|3 && 4|5 && 6|7: -0.047 seconds - int dcterm = d[0]*4; + int dcterm = d[0] * 4; v[0] = v[8] = v[16] = v[24] = v[32] = v[40] = v[48] = v[56] = dcterm; - } else { - STBI__IDCT_1D(d[ 0],d[ 8],d[16],d[24],d[32],d[40],d[48],d[56]) + } + else + { + STBI__IDCT_1D(d[0], d[8], d[16], d[24], d[32], d[40], d[48], d[56]) // constants scaled things up by 1<<12; let's bring them back // down, but keep 2 extra bits of precision - x0 += 512; x1 += 512; x2 += 512; x3 += 512; - v[ 0] = (x0+t3) >> 10; - v[56] = (x0-t3) >> 10; - v[ 8] = (x1+t2) >> 10; - v[48] = (x1-t2) >> 10; - v[16] = (x2+t1) >> 10; - v[40] = (x2-t1) >> 10; - v[24] = (x3+t0) >> 10; - v[32] = (x3-t0) >> 10; + x0 += 512; + x1 += 512; + x2 += 512; + x3 += 512; + v[0] = (x0 + t3) >> 10; + v[56] = (x0 - t3) >> 10; + v[8] = (x1 + t2) >> 10; + v[48] = (x1 - t2) >> 10; + v[16] = (x2 + t1) >> 10; + v[40] = (x2 - t1) >> 10; + v[24] = (x3 + t0) >> 10; + v[32] = (x3 - t0) >> 10; } } - for (i=0, v=val, o=out; i < 8; ++i,v+=8,o+=out_stride) { + for (i = 0, v = val, o = out; i < 8; ++i, v += 8, o += out_stride) + { // no fast case since the first 1D IDCT spread components out - STBI__IDCT_1D(v[0],v[1],v[2],v[3],v[4],v[5],v[6],v[7]) + STBI__IDCT_1D(v[0], v[1], v[2], v[3], v[4], v[5], v[6], v[7]) // constants scaled things up by 1<<12, plus we had 1<<2 from first // loop, plus horizontal and vertical each scale by sqrt(8) so together // we've got an extra 1<<3, so 1<<17 total we need to remove. // so we want to round that, which means adding 0.5 * 1<<17, // aka 65536. Also, we'll end up with -128 to 127 that we want // to encode as 0..255 by adding 128, so we'll add that before the shift - x0 += 65536 + (128<<17); - x1 += 65536 + (128<<17); - x2 += 65536 + (128<<17); - x3 += 65536 + (128<<17); + x0 += 65536 + (128 << 17); + x1 += 65536 + (128 << 17); + x2 += 65536 + (128 << 17); + x3 += 65536 + (128 << 17); // tried computing the shifts into temps, or'ing the temps to see // if any were out of range, but that was slower - o[0] = stbi__clamp((x0+t3) >> 17); - o[7] = stbi__clamp((x0-t3) >> 17); - o[1] = stbi__clamp((x1+t2) >> 17); - o[6] = stbi__clamp((x1-t2) >> 17); - o[2] = stbi__clamp((x2+t1) >> 17); - o[5] = stbi__clamp((x2-t1) >> 17); - o[3] = stbi__clamp((x3+t0) >> 17); - o[4] = stbi__clamp((x3-t0) >> 17); + o[0] = stbi__clamp((x0 + t3) >> 17); + o[7] = stbi__clamp((x0 - t3) >> 17); + o[1] = stbi__clamp((x1 + t2) >> 17); + o[6] = stbi__clamp((x1 - t2) >> 17); + o[2] = stbi__clamp((x2 + t1) >> 17); + o[5] = stbi__clamp((x2 - t1) >> 17); + o[3] = stbi__clamp((x3 + t0) >> 17); + o[4] = stbi__clamp((x3 - t0) >> 17); } } @@ -2533,107 +2801,107 @@ static void stbi__idct_simd(stbi_uc *out, int out_stride, short data[64]) __m128i row0, row1, row2, row3, row4, row5, row6, row7; __m128i tmp; - // dot product constant: even elems=x, odd elems=y - #define dct_const(x,y) _mm_setr_epi16((x),(y),(x),(y),(x),(y),(x),(y)) +// dot product constant: even elems=x, odd elems=y +#define dct_const(x, y) _mm_setr_epi16((x), (y), (x), (y), (x), (y), (x), (y)) - // out(0) = c0[even]*x + c0[odd]*y (c0, x, y 16-bit, out 32-bit) - // out(1) = c1[even]*x + c1[odd]*y - #define dct_rot(out0,out1, x,y,c0,c1) \ - __m128i c0##lo = _mm_unpacklo_epi16((x),(y)); \ - __m128i c0##hi = _mm_unpackhi_epi16((x),(y)); \ - __m128i out0##_l = _mm_madd_epi16(c0##lo, c0); \ - __m128i out0##_h = _mm_madd_epi16(c0##hi, c0); \ - __m128i out1##_l = _mm_madd_epi16(c0##lo, c1); \ - __m128i out1##_h = _mm_madd_epi16(c0##hi, c1) +// out(0) = c0[even]*x + c0[odd]*y (c0, x, y 16-bit, out 32-bit) +// out(1) = c1[even]*x + c1[odd]*y +#define dct_rot(out0, out1, x, y, c0, c1) \ + __m128i c0##lo = _mm_unpacklo_epi16((x), (y)); \ + __m128i c0##hi = _mm_unpackhi_epi16((x), (y)); \ + __m128i out0##_l = _mm_madd_epi16(c0##lo, c0); \ + __m128i out0##_h = _mm_madd_epi16(c0##hi, c0); \ + __m128i out1##_l = _mm_madd_epi16(c0##lo, c1); \ + __m128i out1##_h = _mm_madd_epi16(c0##hi, c1) - // out = in << 12 (in 16-bit, out 32-bit) - #define dct_widen(out, in) \ - __m128i out##_l = _mm_srai_epi32(_mm_unpacklo_epi16(_mm_setzero_si128(), (in)), 4); \ - __m128i out##_h = _mm_srai_epi32(_mm_unpackhi_epi16(_mm_setzero_si128(), (in)), 4) +// out = in << 12 (in 16-bit, out 32-bit) +#define dct_widen(out, in) \ + __m128i out##_l = _mm_srai_epi32(_mm_unpacklo_epi16(_mm_setzero_si128(), (in)), 4); \ + __m128i out##_h = _mm_srai_epi32(_mm_unpackhi_epi16(_mm_setzero_si128(), (in)), 4) - // wide add - #define dct_wadd(out, a, b) \ - __m128i out##_l = _mm_add_epi32(a##_l, b##_l); \ - __m128i out##_h = _mm_add_epi32(a##_h, b##_h) +// wide add +#define dct_wadd(out, a, b) \ + __m128i out##_l = _mm_add_epi32(a##_l, b##_l); \ + __m128i out##_h = _mm_add_epi32(a##_h, b##_h) - // wide sub - #define dct_wsub(out, a, b) \ - __m128i out##_l = _mm_sub_epi32(a##_l, b##_l); \ - __m128i out##_h = _mm_sub_epi32(a##_h, b##_h) +// wide sub +#define dct_wsub(out, a, b) \ + __m128i out##_l = _mm_sub_epi32(a##_l, b##_l); \ + __m128i out##_h = _mm_sub_epi32(a##_h, b##_h) - // butterfly a/b, add bias, then shift by "s" and pack - #define dct_bfly32o(out0, out1, a,b,bias,s) \ - { \ - __m128i abiased_l = _mm_add_epi32(a##_l, bias); \ - __m128i abiased_h = _mm_add_epi32(a##_h, bias); \ - dct_wadd(sum, abiased, b); \ - dct_wsub(dif, abiased, b); \ - out0 = _mm_packs_epi32(_mm_srai_epi32(sum_l, s), _mm_srai_epi32(sum_h, s)); \ - out1 = _mm_packs_epi32(_mm_srai_epi32(dif_l, s), _mm_srai_epi32(dif_h, s)); \ - } +// butterfly a/b, add bias, then shift by "s" and pack +#define dct_bfly32o(out0, out1, a, b, bias, s) \ + { \ + __m128i abiased_l = _mm_add_epi32(a##_l, bias); \ + __m128i abiased_h = _mm_add_epi32(a##_h, bias); \ + dct_wadd(sum, abiased, b); \ + dct_wsub(dif, abiased, b); \ + out0 = _mm_packs_epi32(_mm_srai_epi32(sum_l, s), _mm_srai_epi32(sum_h, s)); \ + out1 = _mm_packs_epi32(_mm_srai_epi32(dif_l, s), _mm_srai_epi32(dif_h, s)); \ + } - // 8-bit interleave step (for transposes) - #define dct_interleave8(a, b) \ - tmp = a; \ - a = _mm_unpacklo_epi8(a, b); \ - b = _mm_unpackhi_epi8(tmp, b) +// 8-bit interleave step (for transposes) +#define dct_interleave8(a, b) \ + tmp = a; \ + a = _mm_unpacklo_epi8(a, b); \ + b = _mm_unpackhi_epi8(tmp, b) - // 16-bit interleave step (for transposes) - #define dct_interleave16(a, b) \ - tmp = a; \ - a = _mm_unpacklo_epi16(a, b); \ - b = _mm_unpackhi_epi16(tmp, b) +// 16-bit interleave step (for transposes) +#define dct_interleave16(a, b) \ + tmp = a; \ + a = _mm_unpacklo_epi16(a, b); \ + b = _mm_unpackhi_epi16(tmp, b) - #define dct_pass(bias,shift) \ - { \ - /* even part */ \ - dct_rot(t2e,t3e, row2,row6, rot0_0,rot0_1); \ - __m128i sum04 = _mm_add_epi16(row0, row4); \ - __m128i dif04 = _mm_sub_epi16(row0, row4); \ - dct_widen(t0e, sum04); \ - dct_widen(t1e, dif04); \ - dct_wadd(x0, t0e, t3e); \ - dct_wsub(x3, t0e, t3e); \ - dct_wadd(x1, t1e, t2e); \ - dct_wsub(x2, t1e, t2e); \ - /* odd part */ \ - dct_rot(y0o,y2o, row7,row3, rot2_0,rot2_1); \ - dct_rot(y1o,y3o, row5,row1, rot3_0,rot3_1); \ - __m128i sum17 = _mm_add_epi16(row1, row7); \ - __m128i sum35 = _mm_add_epi16(row3, row5); \ - dct_rot(y4o,y5o, sum17,sum35, rot1_0,rot1_1); \ - dct_wadd(x4, y0o, y4o); \ - dct_wadd(x5, y1o, y5o); \ - dct_wadd(x6, y2o, y5o); \ - dct_wadd(x7, y3o, y4o); \ - dct_bfly32o(row0,row7, x0,x7,bias,shift); \ - dct_bfly32o(row1,row6, x1,x6,bias,shift); \ - dct_bfly32o(row2,row5, x2,x5,bias,shift); \ - dct_bfly32o(row3,row4, x3,x4,bias,shift); \ - } +#define dct_pass(bias, shift) \ + { \ + /* even part */ \ + dct_rot(t2e, t3e, row2, row6, rot0_0, rot0_1); \ + __m128i sum04 = _mm_add_epi16(row0, row4); \ + __m128i dif04 = _mm_sub_epi16(row0, row4); \ + dct_widen(t0e, sum04); \ + dct_widen(t1e, dif04); \ + dct_wadd(x0, t0e, t3e); \ + dct_wsub(x3, t0e, t3e); \ + dct_wadd(x1, t1e, t2e); \ + dct_wsub(x2, t1e, t2e); \ + /* odd part */ \ + dct_rot(y0o, y2o, row7, row3, rot2_0, rot2_1); \ + dct_rot(y1o, y3o, row5, row1, rot3_0, rot3_1); \ + __m128i sum17 = _mm_add_epi16(row1, row7); \ + __m128i sum35 = _mm_add_epi16(row3, row5); \ + dct_rot(y4o, y5o, sum17, sum35, rot1_0, rot1_1); \ + dct_wadd(x4, y0o, y4o); \ + dct_wadd(x5, y1o, y5o); \ + dct_wadd(x6, y2o, y5o); \ + dct_wadd(x7, y3o, y4o); \ + dct_bfly32o(row0, row7, x0, x7, bias, shift); \ + dct_bfly32o(row1, row6, x1, x6, bias, shift); \ + dct_bfly32o(row2, row5, x2, x5, bias, shift); \ + dct_bfly32o(row3, row4, x3, x4, bias, shift); \ + } __m128i rot0_0 = dct_const(stbi__f2f(0.5411961f), stbi__f2f(0.5411961f) + stbi__f2f(-1.847759065f)); - __m128i rot0_1 = dct_const(stbi__f2f(0.5411961f) + stbi__f2f( 0.765366865f), stbi__f2f(0.5411961f)); + __m128i rot0_1 = dct_const(stbi__f2f(0.5411961f) + stbi__f2f(0.765366865f), stbi__f2f(0.5411961f)); __m128i rot1_0 = dct_const(stbi__f2f(1.175875602f) + stbi__f2f(-0.899976223f), stbi__f2f(1.175875602f)); __m128i rot1_1 = dct_const(stbi__f2f(1.175875602f), stbi__f2f(1.175875602f) + stbi__f2f(-2.562915447f)); - __m128i rot2_0 = dct_const(stbi__f2f(-1.961570560f) + stbi__f2f( 0.298631336f), stbi__f2f(-1.961570560f)); - __m128i rot2_1 = dct_const(stbi__f2f(-1.961570560f), stbi__f2f(-1.961570560f) + stbi__f2f( 3.072711026f)); - __m128i rot3_0 = dct_const(stbi__f2f(-0.390180644f) + stbi__f2f( 2.053119869f), stbi__f2f(-0.390180644f)); - __m128i rot3_1 = dct_const(stbi__f2f(-0.390180644f), stbi__f2f(-0.390180644f) + stbi__f2f( 1.501321110f)); + __m128i rot2_0 = dct_const(stbi__f2f(-1.961570560f) + stbi__f2f(0.298631336f), stbi__f2f(-1.961570560f)); + __m128i rot2_1 = dct_const(stbi__f2f(-1.961570560f), stbi__f2f(-1.961570560f) + stbi__f2f(3.072711026f)); + __m128i rot3_0 = dct_const(stbi__f2f(-0.390180644f) + stbi__f2f(2.053119869f), stbi__f2f(-0.390180644f)); + __m128i rot3_1 = dct_const(stbi__f2f(-0.390180644f), stbi__f2f(-0.390180644f) + stbi__f2f(1.501321110f)); // rounding biases in column/row passes, see stbi__idct_block for explanation. __m128i bias_0 = _mm_set1_epi32(512); - __m128i bias_1 = _mm_set1_epi32(65536 + (128<<17)); + __m128i bias_1 = _mm_set1_epi32(65536 + (128 << 17)); // load - row0 = _mm_load_si128((const __m128i *) (data + 0*8)); - row1 = _mm_load_si128((const __m128i *) (data + 1*8)); - row2 = _mm_load_si128((const __m128i *) (data + 2*8)); - row3 = _mm_load_si128((const __m128i *) (data + 3*8)); - row4 = _mm_load_si128((const __m128i *) (data + 4*8)); - row5 = _mm_load_si128((const __m128i *) (data + 5*8)); - row6 = _mm_load_si128((const __m128i *) (data + 6*8)); - row7 = _mm_load_si128((const __m128i *) (data + 7*8)); + row0 = _mm_load_si128((const __m128i *)(data + 0 * 8)); + row1 = _mm_load_si128((const __m128i *)(data + 1 * 8)); + row2 = _mm_load_si128((const __m128i *)(data + 2 * 8)); + row3 = _mm_load_si128((const __m128i *)(data + 3 * 8)); + row4 = _mm_load_si128((const __m128i *)(data + 4 * 8)); + row5 = _mm_load_si128((const __m128i *)(data + 5 * 8)); + row6 = _mm_load_si128((const __m128i *)(data + 6 * 8)); + row7 = _mm_load_si128((const __m128i *)(data + 7 * 8)); // column pass dct_pass(bias_0, 10); @@ -2681,14 +2949,21 @@ static void stbi__idct_simd(stbi_uc *out, int out_stride, short data[64]) dct_interleave8(p1, p3); // a4b4c4d4... // store - _mm_storel_epi64((__m128i *) out, p0); out += out_stride; - _mm_storel_epi64((__m128i *) out, _mm_shuffle_epi32(p0, 0x4e)); out += out_stride; - _mm_storel_epi64((__m128i *) out, p2); out += out_stride; - _mm_storel_epi64((__m128i *) out, _mm_shuffle_epi32(p2, 0x4e)); out += out_stride; - _mm_storel_epi64((__m128i *) out, p1); out += out_stride; - _mm_storel_epi64((__m128i *) out, _mm_shuffle_epi32(p1, 0x4e)); out += out_stride; - _mm_storel_epi64((__m128i *) out, p3); out += out_stride; - _mm_storel_epi64((__m128i *) out, _mm_shuffle_epi32(p3, 0x4e)); + _mm_storel_epi64((__m128i *)out, p0); + out += out_stride; + _mm_storel_epi64((__m128i *)out, _mm_shuffle_epi32(p0, 0x4e)); + out += out_stride; + _mm_storel_epi64((__m128i *)out, p2); + out += out_stride; + _mm_storel_epi64((__m128i *)out, _mm_shuffle_epi32(p2, 0x4e)); + out += out_stride; + _mm_storel_epi64((__m128i *)out, p1); + out += out_stride; + _mm_storel_epi64((__m128i *)out, _mm_shuffle_epi32(p1, 0x4e)); + out += out_stride; + _mm_storel_epi64((__m128i *)out, p3); + out += out_stride; + _mm_storel_epi64((__m128i *)out, _mm_shuffle_epi32(p3, 0x4e)); } #undef dct_const @@ -2714,97 +2989,97 @@ static void stbi__idct_simd(stbi_uc *out, int out_stride, short data[64]) int16x4_t rot0_0 = vdup_n_s16(stbi__f2f(0.5411961f)); int16x4_t rot0_1 = vdup_n_s16(stbi__f2f(-1.847759065f)); - int16x4_t rot0_2 = vdup_n_s16(stbi__f2f( 0.765366865f)); - int16x4_t rot1_0 = vdup_n_s16(stbi__f2f( 1.175875602f)); + int16x4_t rot0_2 = vdup_n_s16(stbi__f2f(0.765366865f)); + int16x4_t rot1_0 = vdup_n_s16(stbi__f2f(1.175875602f)); int16x4_t rot1_1 = vdup_n_s16(stbi__f2f(-0.899976223f)); int16x4_t rot1_2 = vdup_n_s16(stbi__f2f(-2.562915447f)); int16x4_t rot2_0 = vdup_n_s16(stbi__f2f(-1.961570560f)); int16x4_t rot2_1 = vdup_n_s16(stbi__f2f(-0.390180644f)); - int16x4_t rot3_0 = vdup_n_s16(stbi__f2f( 0.298631336f)); - int16x4_t rot3_1 = vdup_n_s16(stbi__f2f( 2.053119869f)); - int16x4_t rot3_2 = vdup_n_s16(stbi__f2f( 3.072711026f)); - int16x4_t rot3_3 = vdup_n_s16(stbi__f2f( 1.501321110f)); + int16x4_t rot3_0 = vdup_n_s16(stbi__f2f(0.298631336f)); + int16x4_t rot3_1 = vdup_n_s16(stbi__f2f(2.053119869f)); + int16x4_t rot3_2 = vdup_n_s16(stbi__f2f(3.072711026f)); + int16x4_t rot3_3 = vdup_n_s16(stbi__f2f(1.501321110f)); -#define dct_long_mul(out, inq, coeff) \ +#define dct_long_mul(out, inq, coeff) \ int32x4_t out##_l = vmull_s16(vget_low_s16(inq), coeff); \ int32x4_t out##_h = vmull_s16(vget_high_s16(inq), coeff) -#define dct_long_mac(out, acc, inq, coeff) \ +#define dct_long_mac(out, acc, inq, coeff) \ int32x4_t out##_l = vmlal_s16(acc##_l, vget_low_s16(inq), coeff); \ int32x4_t out##_h = vmlal_s16(acc##_h, vget_high_s16(inq), coeff) -#define dct_widen(out, inq) \ +#define dct_widen(out, inq) \ int32x4_t out##_l = vshll_n_s16(vget_low_s16(inq), 12); \ int32x4_t out##_h = vshll_n_s16(vget_high_s16(inq), 12) // wide add -#define dct_wadd(out, a, b) \ +#define dct_wadd(out, a, b) \ int32x4_t out##_l = vaddq_s32(a##_l, b##_l); \ int32x4_t out##_h = vaddq_s32(a##_h, b##_h) // wide sub -#define dct_wsub(out, a, b) \ +#define dct_wsub(out, a, b) \ int32x4_t out##_l = vsubq_s32(a##_l, b##_l); \ int32x4_t out##_h = vsubq_s32(a##_h, b##_h) // butterfly a/b, then shift using "shiftop" by "s" and pack -#define dct_bfly32o(out0,out1, a,b,shiftop,s) \ - { \ - dct_wadd(sum, a, b); \ - dct_wsub(dif, a, b); \ +#define dct_bfly32o(out0, out1, a, b, shiftop, s) \ + { \ + dct_wadd(sum, a, b); \ + dct_wsub(dif, a, b); \ out0 = vcombine_s16(shiftop(sum_l, s), shiftop(sum_h, s)); \ out1 = vcombine_s16(shiftop(dif_l, s), shiftop(dif_h, s)); \ } -#define dct_pass(shiftop, shift) \ - { \ - /* even part */ \ - int16x8_t sum26 = vaddq_s16(row2, row6); \ - dct_long_mul(p1e, sum26, rot0_0); \ - dct_long_mac(t2e, p1e, row6, rot0_1); \ - dct_long_mac(t3e, p1e, row2, rot0_2); \ - int16x8_t sum04 = vaddq_s16(row0, row4); \ - int16x8_t dif04 = vsubq_s16(row0, row4); \ - dct_widen(t0e, sum04); \ - dct_widen(t1e, dif04); \ - dct_wadd(x0, t0e, t3e); \ - dct_wsub(x3, t0e, t3e); \ - dct_wadd(x1, t1e, t2e); \ - dct_wsub(x2, t1e, t2e); \ - /* odd part */ \ - int16x8_t sum15 = vaddq_s16(row1, row5); \ - int16x8_t sum17 = vaddq_s16(row1, row7); \ - int16x8_t sum35 = vaddq_s16(row3, row5); \ - int16x8_t sum37 = vaddq_s16(row3, row7); \ - int16x8_t sumodd = vaddq_s16(sum17, sum35); \ - dct_long_mul(p5o, sumodd, rot1_0); \ - dct_long_mac(p1o, p5o, sum17, rot1_1); \ - dct_long_mac(p2o, p5o, sum35, rot1_2); \ - dct_long_mul(p3o, sum37, rot2_0); \ - dct_long_mul(p4o, sum15, rot2_1); \ - dct_wadd(sump13o, p1o, p3o); \ - dct_wadd(sump24o, p2o, p4o); \ - dct_wadd(sump23o, p2o, p3o); \ - dct_wadd(sump14o, p1o, p4o); \ - dct_long_mac(x4, sump13o, row7, rot3_0); \ - dct_long_mac(x5, sump24o, row5, rot3_1); \ - dct_long_mac(x6, sump23o, row3, rot3_2); \ - dct_long_mac(x7, sump14o, row1, rot3_3); \ - dct_bfly32o(row0,row7, x0,x7,shiftop,shift); \ - dct_bfly32o(row1,row6, x1,x6,shiftop,shift); \ - dct_bfly32o(row2,row5, x2,x5,shiftop,shift); \ - dct_bfly32o(row3,row4, x3,x4,shiftop,shift); \ +#define dct_pass(shiftop, shift) \ + { \ + /* even part */ \ + int16x8_t sum26 = vaddq_s16(row2, row6); \ + dct_long_mul(p1e, sum26, rot0_0); \ + dct_long_mac(t2e, p1e, row6, rot0_1); \ + dct_long_mac(t3e, p1e, row2, rot0_2); \ + int16x8_t sum04 = vaddq_s16(row0, row4); \ + int16x8_t dif04 = vsubq_s16(row0, row4); \ + dct_widen(t0e, sum04); \ + dct_widen(t1e, dif04); \ + dct_wadd(x0, t0e, t3e); \ + dct_wsub(x3, t0e, t3e); \ + dct_wadd(x1, t1e, t2e); \ + dct_wsub(x2, t1e, t2e); \ + /* odd part */ \ + int16x8_t sum15 = vaddq_s16(row1, row5); \ + int16x8_t sum17 = vaddq_s16(row1, row7); \ + int16x8_t sum35 = vaddq_s16(row3, row5); \ + int16x8_t sum37 = vaddq_s16(row3, row7); \ + int16x8_t sumodd = vaddq_s16(sum17, sum35); \ + dct_long_mul(p5o, sumodd, rot1_0); \ + dct_long_mac(p1o, p5o, sum17, rot1_1); \ + dct_long_mac(p2o, p5o, sum35, rot1_2); \ + dct_long_mul(p3o, sum37, rot2_0); \ + dct_long_mul(p4o, sum15, rot2_1); \ + dct_wadd(sump13o, p1o, p3o); \ + dct_wadd(sump24o, p2o, p4o); \ + dct_wadd(sump23o, p2o, p3o); \ + dct_wadd(sump14o, p1o, p4o); \ + dct_long_mac(x4, sump13o, row7, rot3_0); \ + dct_long_mac(x5, sump24o, row5, rot3_1); \ + dct_long_mac(x6, sump23o, row3, rot3_2); \ + dct_long_mac(x7, sump14o, row1, rot3_3); \ + dct_bfly32o(row0, row7, x0, x7, shiftop, shift); \ + dct_bfly32o(row1, row6, x1, x6, shiftop, shift); \ + dct_bfly32o(row2, row5, x2, x5, shiftop, shift); \ + dct_bfly32o(row3, row4, x3, x4, shiftop, shift); \ } // load - row0 = vld1q_s16(data + 0*8); - row1 = vld1q_s16(data + 1*8); - row2 = vld1q_s16(data + 2*8); - row3 = vld1q_s16(data + 3*8); - row4 = vld1q_s16(data + 4*8); - row5 = vld1q_s16(data + 5*8); - row6 = vld1q_s16(data + 6*8); - row7 = vld1q_s16(data + 7*8); + row0 = vld1q_s16(data + 0 * 8); + row1 = vld1q_s16(data + 1 * 8); + row2 = vld1q_s16(data + 2 * 8); + row3 = vld1q_s16(data + 3 * 8); + row4 = vld1q_s16(data + 4 * 8); + row5 = vld1q_s16(data + 5 * 8); + row6 = vld1q_s16(data + 6 * 8); + row7 = vld1q_s16(data + 7 * 8); // add DC bias row0 = vaddq_s16(row0, vsetq_lane_s16(1024, vdupq_n_s16(0), 0)); @@ -2816,9 +3091,25 @@ static void stbi__idct_simd(stbi_uc *out, int out_stride, short data[64]) { // these three map to a single VTRN.16, VTRN.32, and VSWP, respectively. // whether compilers actually get this is another story, sadly. -#define dct_trn16(x, y) { int16x8x2_t t = vtrnq_s16(x, y); x = t.val[0]; y = t.val[1]; } -#define dct_trn32(x, y) { int32x4x2_t t = vtrnq_s32(vreinterpretq_s32_s16(x), vreinterpretq_s32_s16(y)); x = vreinterpretq_s16_s32(t.val[0]); y = vreinterpretq_s16_s32(t.val[1]); } -#define dct_trn64(x, y) { int16x8_t x0 = x; int16x8_t y0 = y; x = vcombine_s16(vget_low_s16(x0), vget_low_s16(y0)); y = vcombine_s16(vget_high_s16(x0), vget_high_s16(y0)); } +#define dct_trn16(x, y) \ + { \ + int16x8x2_t t = vtrnq_s16(x, y); \ + x = t.val[0]; \ + y = t.val[1]; \ + } +#define dct_trn32(x, y) \ + { \ + int32x4x2_t t = vtrnq_s32(vreinterpretq_s32_s16(x), vreinterpretq_s32_s16(y)); \ + x = vreinterpretq_s16_s32(t.val[0]); \ + y = vreinterpretq_s16_s32(t.val[1]); \ + } +#define dct_trn64(x, y) \ + { \ + int16x8_t x0 = x; \ + int16x8_t y0 = y; \ + x = vcombine_s16(vget_low_s16(x0), vget_low_s16(y0)); \ + y = vcombine_s16(vget_high_s16(x0), vget_high_s16(y0)); \ + } // pass 1 dct_trn16(row0, row1); // a0b0a2b2a4b4a6b6 @@ -2861,9 +3152,24 @@ static void stbi__idct_simd(stbi_uc *out, int out_stride, short data[64]) uint8x8_t p7 = vqrshrun_n_s16(row7, 1); // again, these can translate into one instruction, but often don't. -#define dct_trn8_8(x, y) { uint8x8x2_t t = vtrn_u8(x, y); x = t.val[0]; y = t.val[1]; } -#define dct_trn8_16(x, y) { uint16x4x2_t t = vtrn_u16(vreinterpret_u16_u8(x), vreinterpret_u16_u8(y)); x = vreinterpret_u8_u16(t.val[0]); y = vreinterpret_u8_u16(t.val[1]); } -#define dct_trn8_32(x, y) { uint32x2x2_t t = vtrn_u32(vreinterpret_u32_u8(x), vreinterpret_u32_u8(y)); x = vreinterpret_u8_u32(t.val[0]); y = vreinterpret_u8_u32(t.val[1]); } +#define dct_trn8_8(x, y) \ + { \ + uint8x8x2_t t = vtrn_u8(x, y); \ + x = t.val[0]; \ + y = t.val[1]; \ + } +#define dct_trn8_16(x, y) \ + { \ + uint16x4x2_t t = vtrn_u16(vreinterpret_u16_u8(x), vreinterpret_u16_u8(y)); \ + x = vreinterpret_u8_u16(t.val[0]); \ + y = vreinterpret_u8_u16(t.val[1]); \ + } +#define dct_trn8_32(x, y) \ + { \ + uint32x2x2_t t = vtrn_u32(vreinterpret_u32_u8(x), vreinterpret_u32_u8(y)); \ + x = vreinterpret_u8_u32(t.val[0]); \ + y = vreinterpret_u8_u32(t.val[1]); \ + } // sadly can't use interleaved stores here since we only write // 8 bytes to each scan line! @@ -2887,13 +3193,20 @@ static void stbi__idct_simd(stbi_uc *out, int out_stride, short data[64]) dct_trn8_32(p3, p7); // store - vst1_u8(out, p0); out += out_stride; - vst1_u8(out, p1); out += out_stride; - vst1_u8(out, p2); out += out_stride; - vst1_u8(out, p3); out += out_stride; - vst1_u8(out, p4); out += out_stride; - vst1_u8(out, p5); out += out_stride; - vst1_u8(out, p6); out += out_stride; + vst1_u8(out, p0); + out += out_stride; + vst1_u8(out, p1); + out += out_stride; + vst1_u8(out, p2); + out += out_stride; + vst1_u8(out, p3); + out += out_stride; + vst1_u8(out, p4); + out += out_stride; + vst1_u8(out, p5); + out += out_stride; + vst1_u8(out, p6); + out += out_stride; vst1_u8(out, p7); #undef dct_trn8_8 @@ -2912,16 +3225,22 @@ static void stbi__idct_simd(stbi_uc *out, int out_stride, short data[64]) #endif // STBI_NEON -#define STBI__MARKER_none 0xff +#define STBI__MARKER_none 0xff // if there's a pending marker from the entropy stream, return that // otherwise, fetch from the stream and get a marker. if there's no // marker, return 0xff, which is never a valid marker value static stbi_uc stbi__get_marker(stbi__jpeg *j) { stbi_uc x; - if (j->marker != STBI__MARKER_none) { x = j->marker; j->marker = STBI__MARKER_none; return x; } + if (j->marker != STBI__MARKER_none) + { + x = j->marker; + j->marker = STBI__MARKER_none; + return x; + } x = stbi__get8(j->s); - if (x != 0xff) return STBI__MARKER_none; + if (x != 0xff) + return STBI__MARKER_none; while (x == 0xff) x = stbi__get8(j->s); // consume repeated 0xff fill bytes return x; @@ -2929,7 +3248,7 @@ static stbi_uc stbi__get_marker(stbi__jpeg *j) // in each scan, we'll have scan_n components, and the order // of the components is specified by order[] -#define STBI__RESTART(x) ((x) >= 0xd0 && (x) <= 0xd7) +#define STBI__RESTART(x) ((x) >= 0xd0 && (x) <= 0xd7) // after a restart interval, stbi__jpeg_reset the entropy decoder and // the dc prediction @@ -2949,107 +3268,144 @@ static void stbi__jpeg_reset(stbi__jpeg *j) static int stbi__parse_entropy_coded_data(stbi__jpeg *z) { stbi__jpeg_reset(z); - if (!z->progressive) { - if (z->scan_n == 1) { - int i,j; + if (!z->progressive) + { + if (z->scan_n == 1) + { + int i, j; STBI_SIMD_ALIGN(short, data[64]); int n = z->order[0]; // non-interleaved data, we just need to process one block at a time, // in trivial scanline order // number of blocks to do just depends on how many actual "pixels" this // component has, independent of interleaved MCU blocking and such - int w = (z->img_comp[n].x+7) >> 3; - int h = (z->img_comp[n].y+7) >> 3; - for (j=0; j < h; ++j) { - for (i=0; i < w; ++i) { + int w = (z->img_comp[n].x + 7) >> 3; + int h = (z->img_comp[n].y + 7) >> 3; + for (j = 0; j < h; ++j) + { + for (i = 0; i < w; ++i) + { int ha = z->img_comp[n].ha; - if (!stbi__jpeg_decode_block(z, data, z->huff_dc+z->img_comp[n].hd, z->huff_ac+ha, z->fast_ac[ha], n, z->dequant[z->img_comp[n].tq])) return 0; - z->idct_block_kernel(z->img_comp[n].data+z->img_comp[n].w2*j*8+i*8, z->img_comp[n].w2, data); + if (!stbi__jpeg_decode_block(z, data, z->huff_dc + z->img_comp[n].hd, z->huff_ac + ha, z->fast_ac[ha], n, z->dequant[z->img_comp[n].tq])) + return 0; + z->idct_block_kernel(z->img_comp[n].data + z->img_comp[n].w2 * j * 8 + i * 8, z->img_comp[n].w2, data); // every data block is an MCU, so countdown the restart interval - if (--z->todo <= 0) { - if (z->code_bits < 24) stbi__grow_buffer_unsafe(z); + if (--z->todo <= 0) + { + if (z->code_bits < 24) + stbi__grow_buffer_unsafe(z); // if it's NOT a restart, then just bail, so we get corrupt data // rather than no data - if (!STBI__RESTART(z->marker)) return 1; - stbi__jpeg_reset(z); - } - } - } - return 1; - } else { // interleaved - int i,j,k,x,y; - STBI_SIMD_ALIGN(short, data[64]); - for (j=0; j < z->img_mcu_y; ++j) { - for (i=0; i < z->img_mcu_x; ++i) { - // scan an interleaved mcu... process scan_n components in order - for (k=0; k < z->scan_n; ++k) { - int n = z->order[k]; - // scan out an mcu's worth of this component; that's just determined - // by the basic H and V specified for the component - for (y=0; y < z->img_comp[n].v; ++y) { - for (x=0; x < z->img_comp[n].h; ++x) { - int x2 = (i*z->img_comp[n].h + x)*8; - int y2 = (j*z->img_comp[n].v + y)*8; - int ha = z->img_comp[n].ha; - if (!stbi__jpeg_decode_block(z, data, z->huff_dc+z->img_comp[n].hd, z->huff_ac+ha, z->fast_ac[ha], n, z->dequant[z->img_comp[n].tq])) return 0; - z->idct_block_kernel(z->img_comp[n].data+z->img_comp[n].w2*y2+x2, z->img_comp[n].w2, data); - } - } - } - // after all interleaved components, that's an interleaved MCU, - // so now count down the restart interval - if (--z->todo <= 0) { - if (z->code_bits < 24) stbi__grow_buffer_unsafe(z); - if (!STBI__RESTART(z->marker)) return 1; + if (!STBI__RESTART(z->marker)) + return 1; stbi__jpeg_reset(z); } } } return 1; } - } else { - if (z->scan_n == 1) { - int i,j; - int n = z->order[0]; - // non-interleaved data, we just need to process one block at a time, - // in trivial scanline order - // number of blocks to do just depends on how many actual "pixels" this - // component has, independent of interleaved MCU blocking and such - int w = (z->img_comp[n].x+7) >> 3; - int h = (z->img_comp[n].y+7) >> 3; - for (j=0; j < h; ++j) { - for (i=0; i < w; ++i) { - short *data = z->img_comp[n].coeff + 64 * (i + j * z->img_comp[n].coeff_w); - if (z->spec_start == 0) { - if (!stbi__jpeg_decode_block_prog_dc(z, data, &z->huff_dc[z->img_comp[n].hd], n)) - return 0; - } else { - int ha = z->img_comp[n].ha; - if (!stbi__jpeg_decode_block_prog_ac(z, data, &z->huff_ac[ha], z->fast_ac[ha])) - return 0; + else + { // interleaved + int i, j, k, x, y; + STBI_SIMD_ALIGN(short, data[64]); + for (j = 0; j < z->img_mcu_y; ++j) + { + for (i = 0; i < z->img_mcu_x; ++i) + { + // scan an interleaved mcu... process scan_n components in order + for (k = 0; k < z->scan_n; ++k) + { + int n = z->order[k]; + // scan out an mcu's worth of this component; that's just determined + // by the basic H and V specified for the component + for (y = 0; y < z->img_comp[n].v; ++y) + { + for (x = 0; x < z->img_comp[n].h; ++x) + { + int x2 = (i * z->img_comp[n].h + x) * 8; + int y2 = (j * z->img_comp[n].v + y) * 8; + int ha = z->img_comp[n].ha; + if (!stbi__jpeg_decode_block(z, data, z->huff_dc + z->img_comp[n].hd, z->huff_ac + ha, z->fast_ac[ha], n, z->dequant[z->img_comp[n].tq])) + return 0; + z->idct_block_kernel(z->img_comp[n].data + z->img_comp[n].w2 * y2 + x2, z->img_comp[n].w2, data); + } + } } - // every data block is an MCU, so countdown the restart interval - if (--z->todo <= 0) { - if (z->code_bits < 24) stbi__grow_buffer_unsafe(z); - if (!STBI__RESTART(z->marker)) return 1; + // after all interleaved components, that's an interleaved MCU, + // so now count down the restart interval + if (--z->todo <= 0) + { + if (z->code_bits < 24) + stbi__grow_buffer_unsafe(z); + if (!STBI__RESTART(z->marker)) + return 1; stbi__jpeg_reset(z); } } } return 1; - } else { // interleaved - int i,j,k,x,y; - for (j=0; j < z->img_mcu_y; ++j) { - for (i=0; i < z->img_mcu_x; ++i) { + } + } + else + { + if (z->scan_n == 1) + { + int i, j; + int n = z->order[0]; + // non-interleaved data, we just need to process one block at a time, + // in trivial scanline order + // number of blocks to do just depends on how many actual "pixels" this + // component has, independent of interleaved MCU blocking and such + int w = (z->img_comp[n].x + 7) >> 3; + int h = (z->img_comp[n].y + 7) >> 3; + for (j = 0; j < h; ++j) + { + for (i = 0; i < w; ++i) + { + short *data = z->img_comp[n].coeff + 64 * (i + j * z->img_comp[n].coeff_w); + if (z->spec_start == 0) + { + if (!stbi__jpeg_decode_block_prog_dc(z, data, &z->huff_dc[z->img_comp[n].hd], n)) + return 0; + } + else + { + int ha = z->img_comp[n].ha; + if (!stbi__jpeg_decode_block_prog_ac(z, data, &z->huff_ac[ha], z->fast_ac[ha])) + return 0; + } + // every data block is an MCU, so countdown the restart interval + if (--z->todo <= 0) + { + if (z->code_bits < 24) + stbi__grow_buffer_unsafe(z); + if (!STBI__RESTART(z->marker)) + return 1; + stbi__jpeg_reset(z); + } + } + } + return 1; + } + else + { // interleaved + int i, j, k, x, y; + for (j = 0; j < z->img_mcu_y; ++j) + { + for (i = 0; i < z->img_mcu_x; ++i) + { // scan an interleaved mcu... process scan_n components in order - for (k=0; k < z->scan_n; ++k) { + for (k = 0; k < z->scan_n; ++k) + { int n = z->order[k]; // scan out an mcu's worth of this component; that's just determined // by the basic H and V specified for the component - for (y=0; y < z->img_comp[n].v; ++y) { - for (x=0; x < z->img_comp[n].h; ++x) { - int x2 = (i*z->img_comp[n].h + x); - int y2 = (j*z->img_comp[n].v + y); + for (y = 0; y < z->img_comp[n].v; ++y) + { + for (x = 0; x < z->img_comp[n].h; ++x) + { + int x2 = (i * z->img_comp[n].h + x); + int y2 = (j * z->img_comp[n].v + y); short *data = z->img_comp[n].coeff + 64 * (x2 + y2 * z->img_comp[n].coeff_w); if (!stbi__jpeg_decode_block_prog_dc(z, data, &z->huff_dc[z->img_comp[n].hd], n)) return 0; @@ -3058,9 +3414,12 @@ static int stbi__parse_entropy_coded_data(stbi__jpeg *z) } // after all interleaved components, that's an interleaved MCU, // so now count down the restart interval - if (--z->todo <= 0) { - if (z->code_bits < 24) stbi__grow_buffer_unsafe(z); - if (!STBI__RESTART(z->marker)) return 1; + if (--z->todo <= 0) + { + if (z->code_bits < 24) + stbi__grow_buffer_unsafe(z); + if (!STBI__RESTART(z->marker)) + return 1; stbi__jpeg_reset(z); } } @@ -3073,23 +3432,27 @@ static int stbi__parse_entropy_coded_data(stbi__jpeg *z) static void stbi__jpeg_dequantize(short *data, stbi__uint16 *dequant) { int i; - for (i=0; i < 64; ++i) + for (i = 0; i < 64; ++i) data[i] *= dequant[i]; } static void stbi__jpeg_finish(stbi__jpeg *z) { - if (z->progressive) { + if (z->progressive) + { // dequantize and idct the data - int i,j,n; - for (n=0; n < z->s->img_n; ++n) { - int w = (z->img_comp[n].x+7) >> 3; - int h = (z->img_comp[n].y+7) >> 3; - for (j=0; j < h; ++j) { - for (i=0; i < w; ++i) { + int i, j, n; + for (n = 0; n < z->s->img_n; ++n) + { + int w = (z->img_comp[n].x + 7) >> 3; + int h = (z->img_comp[n].y + 7) >> 3; + for (j = 0; j < h; ++j) + { + for (i = 0; i < w; ++i) + { short *data = z->img_comp[n].coeff + 64 * (i + j * z->img_comp[n].coeff_w); stbi__jpeg_dequantize(data, z->dequant[z->img_comp[n].tq]); - z->idct_block_kernel(z->img_comp[n].data+z->img_comp[n].w2*j*8+i*8, z->img_comp[n].w2, data); + z->idct_block_kernel(z->img_comp[n].data + z->img_comp[n].w2 * j * 8 + i * 8, z->img_comp[n].w2, data); } } } @@ -3099,94 +3462,114 @@ static void stbi__jpeg_finish(stbi__jpeg *z) static int stbi__process_marker(stbi__jpeg *z, int m) { int L; - switch (m) { - case STBI__MARKER_none: // no marker found - return stbi__err("expected marker","Corrupt JPEG"); + switch (m) + { + case STBI__MARKER_none: // no marker found + return stbi__err("expected marker", "Corrupt JPEG"); - case 0xDD: // DRI - specify restart interval - if (stbi__get16be(z->s) != 4) return stbi__err("bad DRI len","Corrupt JPEG"); - z->restart_interval = stbi__get16be(z->s); - return 1; + case 0xDD: // DRI - specify restart interval + if (stbi__get16be(z->s) != 4) + return stbi__err("bad DRI len", "Corrupt JPEG"); + z->restart_interval = stbi__get16be(z->s); + return 1; - case 0xDB: // DQT - define quantization table - L = stbi__get16be(z->s)-2; - while (L > 0) { - int q = stbi__get8(z->s); - int p = q >> 4, sixteen = (p != 0); - int t = q & 15,i; - if (p != 0 && p != 1) return stbi__err("bad DQT type","Corrupt JPEG"); - if (t > 3) return stbi__err("bad DQT table","Corrupt JPEG"); + case 0xDB: // DQT - define quantization table + L = stbi__get16be(z->s) - 2; + while (L > 0) + { + int q = stbi__get8(z->s); + int p = q >> 4, sixteen = (p != 0); + int t = q & 15, i; + if (p != 0 && p != 1) + return stbi__err("bad DQT type", "Corrupt JPEG"); + if (t > 3) + return stbi__err("bad DQT table", "Corrupt JPEG"); - for (i=0; i < 64; ++i) - z->dequant[t][stbi__jpeg_dezigzag[i]] = (stbi__uint16)(sixteen ? stbi__get16be(z->s) : stbi__get8(z->s)); - L -= (sixteen ? 129 : 65); + for (i = 0; i < 64; ++i) + z->dequant[t][stbi__jpeg_dezigzag[i]] = (stbi__uint16)(sixteen ? stbi__get16be(z->s) : stbi__get8(z->s)); + L -= (sixteen ? 129 : 65); + } + return L == 0; + + case 0xC4: // DHT - define huffman table + L = stbi__get16be(z->s) - 2; + while (L > 0) + { + stbi_uc *v; + int sizes[16], i, n = 0; + int q = stbi__get8(z->s); + int tc = q >> 4; + int th = q & 15; + if (tc > 1 || th > 3) + return stbi__err("bad DHT header", "Corrupt JPEG"); + for (i = 0; i < 16; ++i) + { + sizes[i] = stbi__get8(z->s); + n += sizes[i]; } - return L==0; - - case 0xC4: // DHT - define huffman table - L = stbi__get16be(z->s)-2; - while (L > 0) { - stbi_uc *v; - int sizes[16],i,n=0; - int q = stbi__get8(z->s); - int tc = q >> 4; - int th = q & 15; - if (tc > 1 || th > 3) return stbi__err("bad DHT header","Corrupt JPEG"); - for (i=0; i < 16; ++i) { - sizes[i] = stbi__get8(z->s); - n += sizes[i]; - } - if(n > 256) return stbi__err("bad DHT header","Corrupt JPEG"); // Loop over i < n would write past end of values! - L -= 17; - if (tc == 0) { - if (!stbi__build_huffman(z->huff_dc+th, sizes)) return 0; - v = z->huff_dc[th].values; - } else { - if (!stbi__build_huffman(z->huff_ac+th, sizes)) return 0; - v = z->huff_ac[th].values; - } - for (i=0; i < n; ++i) - v[i] = stbi__get8(z->s); - if (tc != 0) - stbi__build_fast_ac(z->fast_ac[th], z->huff_ac + th); - L -= n; + if (n > 256) + return stbi__err("bad DHT header", "Corrupt JPEG"); // Loop over i < n would write past end of values! + L -= 17; + if (tc == 0) + { + if (!stbi__build_huffman(z->huff_dc + th, sizes)) + return 0; + v = z->huff_dc[th].values; } - return L==0; + else + { + if (!stbi__build_huffman(z->huff_ac + th, sizes)) + return 0; + v = z->huff_ac[th].values; + } + for (i = 0; i < n; ++i) + v[i] = stbi__get8(z->s); + if (tc != 0) + stbi__build_fast_ac(z->fast_ac[th], z->huff_ac + th); + L -= n; + } + return L == 0; } // check for comment block or APP blocks - if ((m >= 0xE0 && m <= 0xEF) || m == 0xFE) { + if ((m >= 0xE0 && m <= 0xEF) || m == 0xFE) + { L = stbi__get16be(z->s); - if (L < 2) { + if (L < 2) + { if (m == 0xFE) - return stbi__err("bad COM len","Corrupt JPEG"); + return stbi__err("bad COM len", "Corrupt JPEG"); else - return stbi__err("bad APP len","Corrupt JPEG"); + return stbi__err("bad APP len", "Corrupt JPEG"); } L -= 2; - if (m == 0xE0 && L >= 5) { // JFIF APP0 segment - static const unsigned char tag[5] = {'J','F','I','F','\0'}; + if (m == 0xE0 && L >= 5) + { // JFIF APP0 segment + static const unsigned char tag[5] = {'J', 'F', 'I', 'F', '\0'}; int ok = 1; int i; - for (i=0; i < 5; ++i) + for (i = 0; i < 5; ++i) if (stbi__get8(z->s) != tag[i]) ok = 0; L -= 5; if (ok) z->jfif = 1; - } else if (m == 0xEE && L >= 12) { // Adobe APP14 segment - static const unsigned char tag[6] = {'A','d','o','b','e','\0'}; + } + else if (m == 0xEE && L >= 12) + { // Adobe APP14 segment + static const unsigned char tag[6] = {'A', 'd', 'o', 'b', 'e', '\0'}; int ok = 1; int i; - for (i=0; i < 6; ++i) + for (i = 0; i < 6; ++i) if (stbi__get8(z->s) != tag[i]) ok = 0; L -= 6; - if (ok) { - stbi__get8(z->s); // version - stbi__get16be(z->s); // flags0 - stbi__get16be(z->s); // flags1 + if (ok) + { + stbi__get8(z->s); // version + stbi__get16be(z->s); // flags0 + stbi__get16be(z->s); // flags1 z->app14_color_transform = stbi__get8(z->s); // color transform L -= 6; } @@ -3196,7 +3579,7 @@ static int stbi__process_marker(stbi__jpeg *z, int m) return 1; } - return stbi__err("unknown marker","Corrupt JPEG"); + return stbi__err("unknown marker", "Corrupt JPEG"); } // after we see SOS @@ -3205,33 +3588,46 @@ static int stbi__process_scan_header(stbi__jpeg *z) int i; int Ls = stbi__get16be(z->s); z->scan_n = stbi__get8(z->s); - if (z->scan_n < 1 || z->scan_n > 4 || z->scan_n > (int) z->s->img_n) return stbi__err("bad SOS component count","Corrupt JPEG"); - if (Ls != 6+2*z->scan_n) return stbi__err("bad SOS len","Corrupt JPEG"); - for (i=0; i < z->scan_n; ++i) { + if (z->scan_n < 1 || z->scan_n > 4 || z->scan_n > (int)z->s->img_n) + return stbi__err("bad SOS component count", "Corrupt JPEG"); + if (Ls != 6 + 2 * z->scan_n) + return stbi__err("bad SOS len", "Corrupt JPEG"); + for (i = 0; i < z->scan_n; ++i) + { int id = stbi__get8(z->s), which; int q = stbi__get8(z->s); for (which = 0; which < z->s->img_n; ++which) if (z->img_comp[which].id == id) break; - if (which == z->s->img_n) return 0; // no match - z->img_comp[which].hd = q >> 4; if (z->img_comp[which].hd > 3) return stbi__err("bad DC huff","Corrupt JPEG"); - z->img_comp[which].ha = q & 15; if (z->img_comp[which].ha > 3) return stbi__err("bad AC huff","Corrupt JPEG"); + if (which == z->s->img_n) + return 0; // no match + z->img_comp[which].hd = q >> 4; + if (z->img_comp[which].hd > 3) + return stbi__err("bad DC huff", "Corrupt JPEG"); + z->img_comp[which].ha = q & 15; + if (z->img_comp[which].ha > 3) + return stbi__err("bad AC huff", "Corrupt JPEG"); z->order[i] = which; } { int aa; z->spec_start = stbi__get8(z->s); - z->spec_end = stbi__get8(z->s); // should be 63, but might be 0 + z->spec_end = stbi__get8(z->s); // should be 63, but might be 0 aa = stbi__get8(z->s); z->succ_high = (aa >> 4); - z->succ_low = (aa & 15); - if (z->progressive) { - if (z->spec_start > 63 || z->spec_end > 63 || z->spec_start > z->spec_end || z->succ_high > 13 || z->succ_low > 13) + z->succ_low = (aa & 15); + if (z->progressive) + { + if (z->spec_start > 63 || z->spec_end > 63 || z->spec_start > z->spec_end || z->succ_high > 13 || z->succ_low > 13) + return stbi__err("bad SOS", "Corrupt JPEG"); + } + else + { + if (z->spec_start != 0) + return stbi__err("bad SOS", "Corrupt JPEG"); + if (z->succ_high != 0 || z->succ_low != 0) return stbi__err("bad SOS", "Corrupt JPEG"); - } else { - if (z->spec_start != 0) return stbi__err("bad SOS","Corrupt JPEG"); - if (z->succ_high != 0 || z->succ_low != 0) return stbi__err("bad SOS","Corrupt JPEG"); z->spec_end = 63; } } @@ -3242,18 +3638,22 @@ static int stbi__process_scan_header(stbi__jpeg *z) static int stbi__free_jpeg_components(stbi__jpeg *z, int ncomp, int why) { int i; - for (i=0; i < ncomp; ++i) { - if (z->img_comp[i].raw_data) { + for (i = 0; i < ncomp; ++i) + { + if (z->img_comp[i].raw_data) + { STBI_FREE(z->img_comp[i].raw_data); z->img_comp[i].raw_data = NULL; z->img_comp[i].data = NULL; } - if (z->img_comp[i].raw_coeff) { + if (z->img_comp[i].raw_coeff) + { STBI_FREE(z->img_comp[i].raw_coeff); z->img_comp[i].raw_coeff = 0; z->img_comp[i].coeff = 0; } - if (z->img_comp[i].linebuf) { + if (z->img_comp[i].linebuf) + { STBI_FREE(z->img_comp[i].linebuf); z->img_comp[i].linebuf = NULL; } @@ -3264,49 +3664,77 @@ static int stbi__free_jpeg_components(stbi__jpeg *z, int ncomp, int why) static int stbi__process_frame_header(stbi__jpeg *z, int scan) { stbi__context *s = z->s; - int Lf,p,i,q, h_max=1,v_max=1,c; - Lf = stbi__get16be(s); if (Lf < 11) return stbi__err("bad SOF len","Corrupt JPEG"); // JPEG - p = stbi__get8(s); if (p != 8) return stbi__err("only 8-bit","JPEG format not supported: 8-bit only"); // JPEG baseline - s->img_y = stbi__get16be(s); if (s->img_y == 0) return stbi__err("no header height", "JPEG format not supported: delayed height"); // Legal, but we don't handle it--but neither does IJG - s->img_x = stbi__get16be(s); if (s->img_x == 0) return stbi__err("0 width","Corrupt JPEG"); // JPEG requires - if (s->img_y > STBI_MAX_DIMENSIONS) return stbi__err("too large","Very large image (corrupt?)"); - if (s->img_x > STBI_MAX_DIMENSIONS) return stbi__err("too large","Very large image (corrupt?)"); + int Lf, p, i, q, h_max = 1, v_max = 1, c; + Lf = stbi__get16be(s); + if (Lf < 11) + return stbi__err("bad SOF len", "Corrupt JPEG"); // JPEG + p = stbi__get8(s); + if (p != 8) + return stbi__err("only 8-bit", "JPEG format not supported: 8-bit only"); // JPEG baseline + s->img_y = stbi__get16be(s); + if (s->img_y == 0) + return stbi__err("no header height", "JPEG format not supported: delayed height"); // Legal, but we don't handle it--but neither does IJG + s->img_x = stbi__get16be(s); + if (s->img_x == 0) + return stbi__err("0 width", "Corrupt JPEG"); // JPEG requires + if (s->img_y > STBI_MAX_DIMENSIONS) + return stbi__err("too large", "Very large image (corrupt?)"); + if (s->img_x > STBI_MAX_DIMENSIONS) + return stbi__err("too large", "Very large image (corrupt?)"); c = stbi__get8(s); - if (c != 3 && c != 1 && c != 4) return stbi__err("bad component count","Corrupt JPEG"); + if (c != 3 && c != 1 && c != 4) + return stbi__err("bad component count", "Corrupt JPEG"); s->img_n = c; - for (i=0; i < c; ++i) { + for (i = 0; i < c; ++i) + { z->img_comp[i].data = NULL; z->img_comp[i].linebuf = NULL; } - if (Lf != 8+3*s->img_n) return stbi__err("bad SOF len","Corrupt JPEG"); + if (Lf != 8 + 3 * s->img_n) + return stbi__err("bad SOF len", "Corrupt JPEG"); z->rgb = 0; - for (i=0; i < s->img_n; ++i) { - static const unsigned char rgb[3] = { 'R', 'G', 'B' }; + for (i = 0; i < s->img_n; ++i) + { + static const unsigned char rgb[3] = {'R', 'G', 'B'}; z->img_comp[i].id = stbi__get8(s); if (s->img_n == 3 && z->img_comp[i].id == rgb[i]) ++z->rgb; q = stbi__get8(s); - z->img_comp[i].h = (q >> 4); if (!z->img_comp[i].h || z->img_comp[i].h > 4) return stbi__err("bad H","Corrupt JPEG"); - z->img_comp[i].v = q & 15; if (!z->img_comp[i].v || z->img_comp[i].v > 4) return stbi__err("bad V","Corrupt JPEG"); - z->img_comp[i].tq = stbi__get8(s); if (z->img_comp[i].tq > 3) return stbi__err("bad TQ","Corrupt JPEG"); + z->img_comp[i].h = (q >> 4); + if (!z->img_comp[i].h || z->img_comp[i].h > 4) + return stbi__err("bad H", "Corrupt JPEG"); + z->img_comp[i].v = q & 15; + if (!z->img_comp[i].v || z->img_comp[i].v > 4) + return stbi__err("bad V", "Corrupt JPEG"); + z->img_comp[i].tq = stbi__get8(s); + if (z->img_comp[i].tq > 3) + return stbi__err("bad TQ", "Corrupt JPEG"); } - if (scan != STBI__SCAN_load) return 1; + if (scan != STBI__SCAN_load) + return 1; - if (!stbi__mad3sizes_valid(s->img_x, s->img_y, s->img_n, 0)) return stbi__err("too large", "Image too large to decode"); + if (!stbi__mad3sizes_valid(s->img_x, s->img_y, s->img_n, 0)) + return stbi__err("too large", "Image too large to decode"); - for (i=0; i < s->img_n; ++i) { - if (z->img_comp[i].h > h_max) h_max = z->img_comp[i].h; - if (z->img_comp[i].v > v_max) v_max = z->img_comp[i].v; + for (i = 0; i < s->img_n; ++i) + { + if (z->img_comp[i].h > h_max) + h_max = z->img_comp[i].h; + if (z->img_comp[i].v > v_max) + v_max = z->img_comp[i].v; } // check that plane subsampling factors are integer ratios; our resamplers can't deal with fractional ratios // and I've never seen a non-corrupted JPEG file actually use them - for (i=0; i < s->img_n; ++i) { - if (h_max % z->img_comp[i].h != 0) return stbi__err("bad H","Corrupt JPEG"); - if (v_max % z->img_comp[i].v != 0) return stbi__err("bad V","Corrupt JPEG"); + for (i = 0; i < s->img_n; ++i) + { + if (h_max % z->img_comp[i].h != 0) + return stbi__err("bad H", "Corrupt JPEG"); + if (v_max % z->img_comp[i].v != 0) + return stbi__err("bad V", "Corrupt JPEG"); } // compute interleaved mcu info @@ -3315,13 +3743,14 @@ static int stbi__process_frame_header(stbi__jpeg *z, int scan) z->img_mcu_w = h_max * 8; z->img_mcu_h = v_max * 8; // these sizes can't be more than 17 bits - z->img_mcu_x = (s->img_x + z->img_mcu_w-1) / z->img_mcu_w; - z->img_mcu_y = (s->img_y + z->img_mcu_h-1) / z->img_mcu_h; + z->img_mcu_x = (s->img_x + z->img_mcu_w - 1) / z->img_mcu_w; + z->img_mcu_y = (s->img_y + z->img_mcu_h - 1) / z->img_mcu_h; - for (i=0; i < s->img_n; ++i) { + for (i = 0; i < s->img_n; ++i) + { // number of effective pixels (e.g. for non-interleaved MCU) - z->img_comp[i].x = (s->img_x * z->img_comp[i].h + h_max-1) / h_max; - z->img_comp[i].y = (s->img_y * z->img_comp[i].v + v_max-1) / v_max; + z->img_comp[i].x = (s->img_x * z->img_comp[i].h + h_max - 1) / h_max; + z->img_comp[i].y = (s->img_y * z->img_comp[i].v + v_max - 1) / v_max; // to simplify generation, we'll allocate enough memory to decode // the bogus oversized data from using interleaved MCUs and their // big blocks (e.g. a 16x16 iMCU on an image of width 33); we won't @@ -3336,17 +3765,18 @@ static int stbi__process_frame_header(stbi__jpeg *z, int scan) z->img_comp[i].linebuf = NULL; z->img_comp[i].raw_data = stbi__malloc_mad2(z->img_comp[i].w2, z->img_comp[i].h2, 15); if (z->img_comp[i].raw_data == NULL) - return stbi__free_jpeg_components(z, i+1, stbi__err("outofmem", "Out of memory")); + return stbi__free_jpeg_components(z, i + 1, stbi__err("outofmem", "Out of memory")); // align blocks for idct using mmx/sse - z->img_comp[i].data = (stbi_uc*) (((size_t) z->img_comp[i].raw_data + 15) & ~15); - if (z->progressive) { + z->img_comp[i].data = (stbi_uc *)(((size_t)z->img_comp[i].raw_data + 15) & ~15); + if (z->progressive) + { // w2, h2 are multiples of 8 (see above) z->img_comp[i].coeff_w = z->img_comp[i].w2 / 8; z->img_comp[i].coeff_h = z->img_comp[i].h2 / 8; z->img_comp[i].raw_coeff = stbi__malloc_mad3(z->img_comp[i].w2, z->img_comp[i].h2, sizeof(short), 15); if (z->img_comp[i].raw_coeff == NULL) - return stbi__free_jpeg_components(z, i+1, stbi__err("outofmem", "Out of memory")); - z->img_comp[i].coeff = (short*) (((size_t) z->img_comp[i].raw_coeff + 15) & ~15); + return stbi__free_jpeg_components(z, i + 1, stbi__err("outofmem", "Out of memory")); + z->img_comp[i].coeff = (short *)(((size_t)z->img_comp[i].raw_coeff + 15) & ~15); } } @@ -3354,13 +3784,13 @@ static int stbi__process_frame_header(stbi__jpeg *z, int scan) } // use comparisons since in some cases we handle more than one case (e.g. SOF) -#define stbi__DNL(x) ((x) == 0xdc) -#define stbi__SOI(x) ((x) == 0xd8) -#define stbi__EOI(x) ((x) == 0xd9) -#define stbi__SOF(x) ((x) == 0xc0 || (x) == 0xc1 || (x) == 0xc2) -#define stbi__SOS(x) ((x) == 0xda) +#define stbi__DNL(x) ((x) == 0xdc) +#define stbi__SOI(x) ((x) == 0xd8) +#define stbi__EOI(x) ((x) == 0xd9) +#define stbi__SOF(x) ((x) == 0xc0 || (x) == 0xc1 || (x) == 0xc2) +#define stbi__SOS(x) ((x) == 0xda) -#define stbi__SOF_progressive(x) ((x) == 0xc2) +#define stbi__SOF_progressive(x) ((x) == 0xc2) static int stbi__decode_jpeg_header(stbi__jpeg *z, int scan) { @@ -3369,20 +3799,27 @@ static int stbi__decode_jpeg_header(stbi__jpeg *z, int scan) z->app14_color_transform = -1; // valid values are 0,1,2 z->marker = STBI__MARKER_none; // initialize cached marker to empty m = stbi__get_marker(z); - if (!stbi__SOI(m)) return stbi__err("no SOI","Corrupt JPEG"); - if (scan == STBI__SCAN_type) return 1; + if (!stbi__SOI(m)) + return stbi__err("no SOI", "Corrupt JPEG"); + if (scan == STBI__SCAN_type) + return 1; m = stbi__get_marker(z); - while (!stbi__SOF(m)) { - if (!stbi__process_marker(z,m)) return 0; + while (!stbi__SOF(m)) + { + if (!stbi__process_marker(z, m)) + return 0; m = stbi__get_marker(z); - while (m == STBI__MARKER_none) { + while (m == STBI__MARKER_none) + { // some files have extra padding after their blocks, so ok, we'll scan - if (stbi__at_eof(z->s)) return stbi__err("no SOF", "Corrupt JPEG"); + if (stbi__at_eof(z->s)) + return stbi__err("no SOF", "Corrupt JPEG"); m = stbi__get_marker(z); } } z->progressive = stbi__SOF_progressive(m); - if (!stbi__process_frame_header(z, scan)) return 0; + if (!stbi__process_frame_header(z, scan)) + return 0; return 1; } @@ -3390,12 +3827,16 @@ static stbi_uc stbi__skip_jpeg_junk_at_end(stbi__jpeg *j) { // some JPEGs have junk at end, skip over it but if we find what looks // like a valid marker, resume there - while (!stbi__at_eof(j->s)) { + while (!stbi__at_eof(j->s)) + { stbi_uc x = stbi__get8(j->s); - while (x == 0xff) { // might be a marker - if (stbi__at_eof(j->s)) return STBI__MARKER_none; + while (x == 0xff) + { // might be a marker + if (stbi__at_eof(j->s)) + return STBI__MARKER_none; x = stbi__get8(j->s); - if (x != 0x00 && x != 0xff) { + if (x != 0x00 && x != 0xff) + { // not a stuffed zero or lead-in to another marker, looks // like an actual marker, return it return x; @@ -3412,32 +3853,46 @@ static stbi_uc stbi__skip_jpeg_junk_at_end(stbi__jpeg *j) static int stbi__decode_jpeg_image(stbi__jpeg *j) { int m; - for (m = 0; m < 4; m++) { + for (m = 0; m < 4; m++) + { j->img_comp[m].raw_data = NULL; j->img_comp[m].raw_coeff = NULL; } j->restart_interval = 0; - if (!stbi__decode_jpeg_header(j, STBI__SCAN_load)) return 0; + if (!stbi__decode_jpeg_header(j, STBI__SCAN_load)) + return 0; m = stbi__get_marker(j); - while (!stbi__EOI(m)) { - if (stbi__SOS(m)) { - if (!stbi__process_scan_header(j)) return 0; - if (!stbi__parse_entropy_coded_data(j)) return 0; - if (j->marker == STBI__MARKER_none ) { - j->marker = stbi__skip_jpeg_junk_at_end(j); + while (!stbi__EOI(m)) + { + if (stbi__SOS(m)) + { + if (!stbi__process_scan_header(j)) + return 0; + if (!stbi__parse_entropy_coded_data(j)) + return 0; + if (j->marker == STBI__MARKER_none) + { + j->marker = stbi__skip_jpeg_junk_at_end(j); // if we reach eof without hitting a marker, stbi__get_marker() below will fail and we'll eventually return 0 } m = stbi__get_marker(j); if (STBI__RESTART(m)) m = stbi__get_marker(j); - } else if (stbi__DNL(m)) { + } + else if (stbi__DNL(m)) + { int Ld = stbi__get16be(j->s); stbi__uint32 NL = stbi__get16be(j->s); - if (Ld != 4) return stbi__err("bad DNL len", "Corrupt JPEG"); - if (NL != j->s->img_y) return stbi__err("bad DNL height", "Corrupt JPEG"); + if (Ld != 4) + return stbi__err("bad DNL len", "Corrupt JPEG"); + if (NL != j->s->img_y) + return stbi__err("bad DNL height", "Corrupt JPEG"); m = stbi__get_marker(j); - } else { - if (!stbi__process_marker(j, m)) return 1; + } + else + { + if (!stbi__process_marker(j, m)) + return 1; m = stbi__get_marker(j); } } @@ -3449,9 +3904,9 @@ static int stbi__decode_jpeg_image(stbi__jpeg *j) // static jfif-centered resampling (across block boundaries) typedef stbi_uc *(*resample_row_func)(stbi_uc *out, stbi_uc *in0, stbi_uc *in1, - int w, int hs); + int w, int hs); -#define stbi__div4(x) ((stbi_uc) ((x) >> 2)) +#define stbi__div4(x) ((stbi_uc)((x) >> 2)) static stbi_uc *resample_row_1(stbi_uc *out, stbi_uc *in_near, stbi_uc *in_far, int w, int hs) { @@ -3462,37 +3917,39 @@ static stbi_uc *resample_row_1(stbi_uc *out, stbi_uc *in_near, stbi_uc *in_far, return in_near; } -static stbi_uc* stbi__resample_row_v_2(stbi_uc *out, stbi_uc *in_near, stbi_uc *in_far, int w, int hs) +static stbi_uc *stbi__resample_row_v_2(stbi_uc *out, stbi_uc *in_near, stbi_uc *in_far, int w, int hs) { // need to generate two samples vertically for every one in input int i; STBI_NOTUSED(hs); - for (i=0; i < w; ++i) - out[i] = stbi__div4(3*in_near[i] + in_far[i] + 2); + for (i = 0; i < w; ++i) + out[i] = stbi__div4(3 * in_near[i] + in_far[i] + 2); return out; } -static stbi_uc* stbi__resample_row_h_2(stbi_uc *out, stbi_uc *in_near, stbi_uc *in_far, int w, int hs) +static stbi_uc *stbi__resample_row_h_2(stbi_uc *out, stbi_uc *in_near, stbi_uc *in_far, int w, int hs) { // need to generate two samples horizontally for every one in input int i; stbi_uc *input = in_near; - if (w == 1) { + if (w == 1) + { // if only one sample, can't do any interpolation out[0] = out[1] = input[0]; return out; } out[0] = input[0]; - out[1] = stbi__div4(input[0]*3 + input[1] + 2); - for (i=1; i < w-1; ++i) { - int n = 3*input[i]+2; - out[i*2+0] = stbi__div4(n+input[i-1]); - out[i*2+1] = stbi__div4(n+input[i+1]); + out[1] = stbi__div4(input[0] * 3 + input[1] + 2); + for (i = 1; i < w - 1; ++i) + { + int n = 3 * input[i] + 2; + out[i * 2 + 0] = stbi__div4(n + input[i - 1]); + out[i * 2 + 1] = stbi__div4(n + input[i + 1]); } - out[i*2+0] = stbi__div4(input[w-2]*3 + input[w-1] + 2); - out[i*2+1] = input[w-1]; + out[i * 2 + 0] = stbi__div4(input[w - 2] * 3 + input[w - 1] + 2); + out[i * 2 + 1] = input[w - 1]; STBI_NOTUSED(in_far); STBI_NOTUSED(hs); @@ -3500,26 +3957,28 @@ static stbi_uc* stbi__resample_row_h_2(stbi_uc *out, stbi_uc *in_near, stbi_uc return out; } -#define stbi__div16(x) ((stbi_uc) ((x) >> 4)) +#define stbi__div16(x) ((stbi_uc)((x) >> 4)) static stbi_uc *stbi__resample_row_hv_2(stbi_uc *out, stbi_uc *in_near, stbi_uc *in_far, int w, int hs) { // need to generate 2x2 samples for every one in input - int i,t0,t1; - if (w == 1) { - out[0] = out[1] = stbi__div4(3*in_near[0] + in_far[0] + 2); + int i, t0, t1; + if (w == 1) + { + out[0] = out[1] = stbi__div4(3 * in_near[0] + in_far[0] + 2); return out; } - t1 = 3*in_near[0] + in_far[0]; - out[0] = stbi__div4(t1+2); - for (i=1; i < w; ++i) { + t1 = 3 * in_near[0] + in_far[0]; + out[0] = stbi__div4(t1 + 2); + for (i = 1; i < w; ++i) + { t0 = t1; - t1 = 3*in_near[i]+in_far[i]; - out[i*2-1] = stbi__div16(3*t0 + t1 + 8); - out[i*2 ] = stbi__div16(3*t1 + t0 + 8); + t1 = 3 * in_near[i] + in_far[i]; + out[i * 2 - 1] = stbi__div16(3 * t0 + t1 + 8); + out[i * 2] = stbi__div16(3 * t1 + t0 + 8); } - out[w*2-1] = stbi__div4(t1+2); + out[w * 2 - 1] = stbi__div4(t1 + 2); STBI_NOTUSED(hs); @@ -3530,29 +3989,31 @@ static stbi_uc *stbi__resample_row_hv_2(stbi_uc *out, stbi_uc *in_near, stbi_uc static stbi_uc *stbi__resample_row_hv_2_simd(stbi_uc *out, stbi_uc *in_near, stbi_uc *in_far, int w, int hs) { // need to generate 2x2 samples for every one in input - int i=0,t0,t1; + int i = 0, t0, t1; - if (w == 1) { - out[0] = out[1] = stbi__div4(3*in_near[0] + in_far[0] + 2); + if (w == 1) + { + out[0] = out[1] = stbi__div4(3 * in_near[0] + in_far[0] + 2); return out; } - t1 = 3*in_near[0] + in_far[0]; + t1 = 3 * in_near[0] + in_far[0]; // process groups of 8 pixels for as long as we can. // note we can't handle the last pixel in a row in this loop // because we need to handle the filter boundary conditions. - for (; i < ((w-1) & ~7); i += 8) { + for (; i < ((w - 1) & ~7); i += 8) + { #if defined(STBI_SSE2) // load and perform the vertical filtering pass // this uses 3*x + y = 4*x + (y - x) - __m128i zero = _mm_setzero_si128(); - __m128i farb = _mm_loadl_epi64((__m128i *) (in_far + i)); - __m128i nearb = _mm_loadl_epi64((__m128i *) (in_near + i)); - __m128i farw = _mm_unpacklo_epi8(farb, zero); + __m128i zero = _mm_setzero_si128(); + __m128i farb = _mm_loadl_epi64((__m128i *)(in_far + i)); + __m128i nearb = _mm_loadl_epi64((__m128i *)(in_near + i)); + __m128i farw = _mm_unpacklo_epi8(farb, zero); __m128i nearw = _mm_unpacklo_epi8(nearb, zero); - __m128i diff = _mm_sub_epi16(farw, nearw); + __m128i diff = _mm_sub_epi16(farw, nearw); __m128i nears = _mm_slli_epi16(nearw, 2); - __m128i curr = _mm_add_epi16(nears, diff); // current row + __m128i curr = _mm_add_epi16(nears, diff); // current row // horizontal filter works the same based on shifted vers of current // row. "prev" is current row shifted right by 1 pixel; we need to @@ -3562,37 +4023,37 @@ static stbi_uc *stbi__resample_row_hv_2_simd(stbi_uc *out, stbi_uc *in_near, stb __m128i prv0 = _mm_slli_si128(curr, 2); __m128i nxt0 = _mm_srli_si128(curr, 2); __m128i prev = _mm_insert_epi16(prv0, t1, 0); - __m128i next = _mm_insert_epi16(nxt0, 3*in_near[i+8] + in_far[i+8], 7); + __m128i next = _mm_insert_epi16(nxt0, 3 * in_near[i + 8] + in_far[i + 8], 7); // horizontal filter, polyphase implementation since it's convenient: // even pixels = 3*cur + prev = cur*4 + (prev - cur) // odd pixels = 3*cur + next = cur*4 + (next - cur) // note the shared term. - __m128i bias = _mm_set1_epi16(8); + __m128i bias = _mm_set1_epi16(8); __m128i curs = _mm_slli_epi16(curr, 2); __m128i prvd = _mm_sub_epi16(prev, curr); __m128i nxtd = _mm_sub_epi16(next, curr); __m128i curb = _mm_add_epi16(curs, bias); __m128i even = _mm_add_epi16(prvd, curb); - __m128i odd = _mm_add_epi16(nxtd, curb); + __m128i odd = _mm_add_epi16(nxtd, curb); // interleave even and odd pixels, then undo scaling. __m128i int0 = _mm_unpacklo_epi16(even, odd); __m128i int1 = _mm_unpackhi_epi16(even, odd); - __m128i de0 = _mm_srli_epi16(int0, 4); - __m128i de1 = _mm_srli_epi16(int1, 4); + __m128i de0 = _mm_srli_epi16(int0, 4); + __m128i de1 = _mm_srli_epi16(int1, 4); // pack and write output __m128i outv = _mm_packus_epi16(de0, de1); - _mm_storeu_si128((__m128i *) (out + i*2), outv); + _mm_storeu_si128((__m128i *)(out + i * 2), outv); #elif defined(STBI_NEON) // load and perform the vertical filtering pass // this uses 3*x + y = 4*x + (y - x) - uint8x8_t farb = vld1_u8(in_far + i); + uint8x8_t farb = vld1_u8(in_far + i); uint8x8_t nearb = vld1_u8(in_near + i); - int16x8_t diff = vreinterpretq_s16_u16(vsubl_u8(farb, nearb)); + int16x8_t diff = vreinterpretq_s16_u16(vsubl_u8(farb, nearb)); int16x8_t nears = vreinterpretq_s16_u16(vshll_n_u8(nearb, 2)); - int16x8_t curr = vaddq_s16(nears, diff); // current row + int16x8_t curr = vaddq_s16(nears, diff); // current row // horizontal filter works the same based on shifted vers of current // row. "prev" is current row shifted right by 1 pixel; we need to @@ -3602,7 +4063,7 @@ static stbi_uc *stbi__resample_row_hv_2_simd(stbi_uc *out, stbi_uc *in_near, stb int16x8_t prv0 = vextq_s16(curr, curr, 7); int16x8_t nxt0 = vextq_s16(curr, curr, 1); int16x8_t prev = vsetq_lane_s16(t1, prv0, 0); - int16x8_t next = vsetq_lane_s16(3*in_near[i+8] + in_far[i+8], nxt0, 7); + int16x8_t next = vsetq_lane_s16(3 * in_near[i + 8] + in_far[i + 8], nxt0, 7); // horizontal filter, polyphase implementation since it's convenient: // even pixels = 3*cur + prev = cur*4 + (prev - cur) @@ -3612,30 +4073,31 @@ static stbi_uc *stbi__resample_row_hv_2_simd(stbi_uc *out, stbi_uc *in_near, stb int16x8_t prvd = vsubq_s16(prev, curr); int16x8_t nxtd = vsubq_s16(next, curr); int16x8_t even = vaddq_s16(curs, prvd); - int16x8_t odd = vaddq_s16(curs, nxtd); + int16x8_t odd = vaddq_s16(curs, nxtd); // undo scaling and round, then store with even/odd phases interleaved uint8x8x2_t o; o.val[0] = vqrshrun_n_s16(even, 4); - o.val[1] = vqrshrun_n_s16(odd, 4); - vst2_u8(out + i*2, o); + o.val[1] = vqrshrun_n_s16(odd, 4); + vst2_u8(out + i * 2, o); #endif // "previous" value for next iter - t1 = 3*in_near[i+7] + in_far[i+7]; + t1 = 3 * in_near[i + 7] + in_far[i + 7]; } t0 = t1; - t1 = 3*in_near[i] + in_far[i]; - out[i*2] = stbi__div16(3*t1 + t0 + 8); + t1 = 3 * in_near[i] + in_far[i]; + out[i * 2] = stbi__div16(3 * t1 + t0 + 8); - for (++i; i < w; ++i) { + for (++i; i < w; ++i) + { t0 = t1; - t1 = 3*in_near[i]+in_far[i]; - out[i*2-1] = stbi__div16(3*t0 + t1 + 8); - out[i*2 ] = stbi__div16(3*t1 + t0 + 8); + t1 = 3 * in_near[i] + in_far[i]; + out[i * 2 - 1] = stbi__div16(3 * t0 + t1 + 8); + out[i * 2] = stbi__div16(3 * t1 + t0 + 8); } - out[w*2-1] = stbi__div4(t1+2); + out[w * 2 - 1] = stbi__div4(t1 + 2); STBI_NOTUSED(hs); @@ -3646,34 +4108,53 @@ static stbi_uc *stbi__resample_row_hv_2_simd(stbi_uc *out, stbi_uc *in_near, stb static stbi_uc *stbi__resample_row_generic(stbi_uc *out, stbi_uc *in_near, stbi_uc *in_far, int w, int hs) { // resample with nearest-neighbor - int i,j; + int i, j; STBI_NOTUSED(in_far); - for (i=0; i < w; ++i) - for (j=0; j < hs; ++j) - out[i*hs+j] = in_near[i]; + for (i = 0; i < w; ++i) + for (j = 0; j < hs; ++j) + out[i * hs + j] = in_near[i]; return out; } // this is a reduced-precision calculation of YCbCr-to-RGB introduced // to make sure the code produces the same results in both SIMD and scalar -#define stbi__float2fixed(x) (((int) ((x) * 4096.0f + 0.5f)) << 8) +#define stbi__float2fixed(x) (((int)((x) * 4096.0f + 0.5f)) << 8) static void stbi__YCbCr_to_RGB_row(stbi_uc *out, const stbi_uc *y, const stbi_uc *pcb, const stbi_uc *pcr, int count, int step) { int i; - for (i=0; i < count; ++i) { - int y_fixed = (y[i] << 20) + (1<<19); // rounding - int r,g,b; + for (i = 0; i < count; ++i) + { + int y_fixed = (y[i] << 20) + (1 << 19); // rounding + int r, g, b; int cr = pcr[i] - 128; int cb = pcb[i] - 128; - r = y_fixed + cr* stbi__float2fixed(1.40200f); - g = y_fixed + (cr*-stbi__float2fixed(0.71414f)) + ((cb*-stbi__float2fixed(0.34414f)) & 0xffff0000); - b = y_fixed + cb* stbi__float2fixed(1.77200f); + r = y_fixed + cr * stbi__float2fixed(1.40200f); + g = y_fixed + (cr * -stbi__float2fixed(0.71414f)) + ((cb * -stbi__float2fixed(0.34414f)) & 0xffff0000); + b = y_fixed + cb * stbi__float2fixed(1.77200f); r >>= 20; g >>= 20; b >>= 20; - if ((unsigned) r > 255) { if (r < 0) r = 0; else r = 255; } - if ((unsigned) g > 255) { if (g < 0) g = 0; else g = 255; } - if ((unsigned) b > 255) { if (b < 0) b = 0; else b = 255; } + if ((unsigned)r > 255) + { + if (r < 0) + r = 0; + else + r = 255; + } + if ((unsigned)g > 255) + { + if (g < 0) + g = 0; + else + g = 255; + } + if ((unsigned)b > 255) + { + if (b < 0) + b = 0; + else + b = 255; + } out[0] = (stbi_uc)r; out[1] = (stbi_uc)g; out[2] = (stbi_uc)b; @@ -3691,26 +4172,28 @@ static void stbi__YCbCr_to_RGB_simd(stbi_uc *out, stbi_uc const *y, stbi_uc cons // step == 3 is pretty ugly on the final interleave, and i'm not convinced // it's useful in practice (you wouldn't use it for textures, for example). // so just accelerate step == 4 case. - if (step == 4) { + if (step == 4) + { // this is a fairly straightforward implementation and not super-optimized. - __m128i signflip = _mm_set1_epi8(-0x80); - __m128i cr_const0 = _mm_set1_epi16( (short) ( 1.40200f*4096.0f+0.5f)); - __m128i cr_const1 = _mm_set1_epi16( - (short) ( 0.71414f*4096.0f+0.5f)); - __m128i cb_const0 = _mm_set1_epi16( - (short) ( 0.34414f*4096.0f+0.5f)); - __m128i cb_const1 = _mm_set1_epi16( (short) ( 1.77200f*4096.0f+0.5f)); - __m128i y_bias = _mm_set1_epi8((char) (unsigned char) 128); + __m128i signflip = _mm_set1_epi8(-0x80); + __m128i cr_const0 = _mm_set1_epi16((short)(1.40200f * 4096.0f + 0.5f)); + __m128i cr_const1 = _mm_set1_epi16(-(short)(0.71414f * 4096.0f + 0.5f)); + __m128i cb_const0 = _mm_set1_epi16(-(short)(0.34414f * 4096.0f + 0.5f)); + __m128i cb_const1 = _mm_set1_epi16((short)(1.77200f * 4096.0f + 0.5f)); + __m128i y_bias = _mm_set1_epi8((char)(unsigned char)128); __m128i xw = _mm_set1_epi16(255); // alpha channel - for (; i+7 < count; i += 8) { + for (; i + 7 < count; i += 8) + { // load - __m128i y_bytes = _mm_loadl_epi64((__m128i *) (y+i)); - __m128i cr_bytes = _mm_loadl_epi64((__m128i *) (pcr+i)); - __m128i cb_bytes = _mm_loadl_epi64((__m128i *) (pcb+i)); + __m128i y_bytes = _mm_loadl_epi64((__m128i *)(y + i)); + __m128i cr_bytes = _mm_loadl_epi64((__m128i *)(pcr + i)); + __m128i cb_bytes = _mm_loadl_epi64((__m128i *)(pcb + i)); __m128i cr_biased = _mm_xor_si128(cr_bytes, signflip); // -128 __m128i cb_biased = _mm_xor_si128(cb_bytes, signflip); // -128 // unpack to short (and left-shift cr, cb by 8) - __m128i yw = _mm_unpacklo_epi8(y_bias, y_bytes); + __m128i yw = _mm_unpacklo_epi8(y_bias, y_bytes); __m128i crw = _mm_unpacklo_epi8(_mm_setzero_si128(), cr_biased); __m128i cbw = _mm_unpacklo_epi8(_mm_setzero_si128(), cb_biased); @@ -3741,8 +4224,8 @@ static void stbi__YCbCr_to_RGB_simd(stbi_uc *out, stbi_uc const *y, stbi_uc cons __m128i o1 = _mm_unpackhi_epi16(t0, t1); // store - _mm_storeu_si128((__m128i *) (out + 0), o0); - _mm_storeu_si128((__m128i *) (out + 16), o1); + _mm_storeu_si128((__m128i *)(out + 0), o0); + _mm_storeu_si128((__m128i *)(out + 16), o1); out += 32; } } @@ -3750,17 +4233,19 @@ static void stbi__YCbCr_to_RGB_simd(stbi_uc *out, stbi_uc const *y, stbi_uc cons #ifdef STBI_NEON // in this version, step=3 support would be easy to add. but is there demand? - if (step == 4) { + if (step == 4) + { // this is a fairly straightforward implementation and not super-optimized. uint8x8_t signflip = vdup_n_u8(0x80); - int16x8_t cr_const0 = vdupq_n_s16( (short) ( 1.40200f*4096.0f+0.5f)); - int16x8_t cr_const1 = vdupq_n_s16( - (short) ( 0.71414f*4096.0f+0.5f)); - int16x8_t cb_const0 = vdupq_n_s16( - (short) ( 0.34414f*4096.0f+0.5f)); - int16x8_t cb_const1 = vdupq_n_s16( (short) ( 1.77200f*4096.0f+0.5f)); + int16x8_t cr_const0 = vdupq_n_s16((short)(1.40200f * 4096.0f + 0.5f)); + int16x8_t cr_const1 = vdupq_n_s16(-(short)(0.71414f * 4096.0f + 0.5f)); + int16x8_t cb_const0 = vdupq_n_s16(-(short)(0.34414f * 4096.0f + 0.5f)); + int16x8_t cb_const1 = vdupq_n_s16((short)(1.77200f * 4096.0f + 0.5f)); - for (; i+7 < count; i += 8) { + for (; i + 7 < count; i += 8) + { // load - uint8x8_t y_bytes = vld1_u8(y + i); + uint8x8_t y_bytes = vld1_u8(y + i); uint8x8_t cr_bytes = vld1_u8(pcr + i); uint8x8_t cb_bytes = vld1_u8(pcb + i); int8x8_t cr_biased = vreinterpret_s8_u8(vsub_u8(cr_bytes, signflip)); @@ -3789,25 +4274,44 @@ static void stbi__YCbCr_to_RGB_simd(stbi_uc *out, stbi_uc const *y, stbi_uc cons // store, interleaving r/g/b/a vst4_u8(out, o); - out += 8*4; + out += 8 * 4; } } #endif - for (; i < count; ++i) { - int y_fixed = (y[i] << 20) + (1<<19); // rounding - int r,g,b; + for (; i < count; ++i) + { + int y_fixed = (y[i] << 20) + (1 << 19); // rounding + int r, g, b; int cr = pcr[i] - 128; int cb = pcb[i] - 128; - r = y_fixed + cr* stbi__float2fixed(1.40200f); - g = y_fixed + cr*-stbi__float2fixed(0.71414f) + ((cb*-stbi__float2fixed(0.34414f)) & 0xffff0000); - b = y_fixed + cb* stbi__float2fixed(1.77200f); + r = y_fixed + cr * stbi__float2fixed(1.40200f); + g = y_fixed + cr * -stbi__float2fixed(0.71414f) + ((cb * -stbi__float2fixed(0.34414f)) & 0xffff0000); + b = y_fixed + cb * stbi__float2fixed(1.77200f); r >>= 20; g >>= 20; b >>= 20; - if ((unsigned) r > 255) { if (r < 0) r = 0; else r = 255; } - if ((unsigned) g > 255) { if (g < 0) g = 0; else g = 255; } - if ((unsigned) b > 255) { if (b < 0) b = 0; else b = 255; } + if ((unsigned)r > 255) + { + if (r < 0) + r = 0; + else + r = 255; + } + if ((unsigned)g > 255) + { + if (g < 0) + g = 0; + else + g = 255; + } + if ((unsigned)b > 255) + { + if (b < 0) + b = 0; + else + b = 255; + } out[0] = (stbi_uc)r; out[1] = (stbi_uc)g; out[2] = (stbi_uc)b; @@ -3825,7 +4329,8 @@ static void stbi__setup_jpeg(stbi__jpeg *j) j->resample_row_hv_2_kernel = stbi__resample_row_hv_2; #ifdef STBI_SSE2 - if (stbi__sse2_available()) { + if (stbi__sse2_available()) + { j->idct_block_kernel = stbi__idct_simd; j->YCbCr_to_RGB_kernel = stbi__YCbCr_to_RGB_simd; j->resample_row_hv_2_kernel = stbi__resample_row_hv_2_simd; @@ -3848,8 +4353,8 @@ static void stbi__cleanup_jpeg(stbi__jpeg *j) typedef struct { resample_row_func resample; - stbi_uc *line0,*line1; - int hs,vs; // expansion factor in each axis + stbi_uc *line0, *line1; + int hs, vs; // expansion factor in each axis int w_lores; // horizontal pixels pre-expansion int ystep; // how far through vertical expansion we are int ypos; // which pre-expansion row we're on @@ -3858,8 +4363,8 @@ typedef struct // fast 0..255 * 0..255 => 0..255 rounded multiplication static stbi_uc stbi__blinn_8x8(stbi_uc x, stbi_uc y) { - unsigned int t = x*y + 128; - return (stbi_uc) ((t + (t >>8)) >> 8); + unsigned int t = x * y + 128; + return (stbi_uc)((t + (t >> 8)) >> 8); } static stbi_uc *load_jpeg_image(stbi__jpeg *z, int *out_x, int *out_y, int *comp, int req_comp) @@ -3868,13 +4373,19 @@ static stbi_uc *load_jpeg_image(stbi__jpeg *z, int *out_x, int *out_y, int *comp z->s->img_n = 0; // make stbi__cleanup_jpeg safe // validate req_comp - if (req_comp < 0 || req_comp > 4) return stbi__errpuc("bad req_comp", "Internal error"); + if (req_comp < 0 || req_comp > 4) + return stbi__errpuc("bad req_comp", "Internal error"); // load a jpeg image from whichever source, but leave in YCbCr format - if (!stbi__decode_jpeg_image(z)) { stbi__cleanup_jpeg(z); return NULL; } + if (!stbi__decode_jpeg_image(z)) + { + stbi__cleanup_jpeg(z); + return NULL; + } // determine actual number of components to generate - n = req_comp ? req_comp : z->s->img_n >= 3 ? 3 : 1; + n = req_comp ? req_comp : z->s->img_n >= 3 ? 3 + : 1; is_rgb = z->s->img_n == 3 && (z->rgb == 3 || (z->app14_color_transform == 0 && !z->jfif)); @@ -3885,77 +4396,108 @@ static stbi_uc *load_jpeg_image(stbi__jpeg *z, int *out_x, int *out_y, int *comp // nothing to do if no components requested; check this now to avoid // accessing uninitialized coutput[0] later - if (decode_n <= 0) { stbi__cleanup_jpeg(z); return NULL; } + if (decode_n <= 0) + { + stbi__cleanup_jpeg(z); + return NULL; + } // resample and color-convert { int k; - unsigned int i,j; + unsigned int i, j; stbi_uc *output; - stbi_uc *coutput[4] = { NULL, NULL, NULL, NULL }; + stbi_uc *coutput[4] = {NULL, NULL, NULL, NULL}; stbi__resample res_comp[4]; - for (k=0; k < decode_n; ++k) { + for (k = 0; k < decode_n; ++k) + { stbi__resample *r = &res_comp[k]; // allocate line buffer big enough for upsampling off the edges // with upsample factor of 4 - z->img_comp[k].linebuf = (stbi_uc *) stbi__malloc(z->s->img_x + 3); - if (!z->img_comp[k].linebuf) { stbi__cleanup_jpeg(z); return stbi__errpuc("outofmem", "Out of memory"); } + z->img_comp[k].linebuf = (stbi_uc *)stbi__malloc(z->s->img_x + 3); + if (!z->img_comp[k].linebuf) + { + stbi__cleanup_jpeg(z); + return stbi__errpuc("outofmem", "Out of memory"); + } - r->hs = z->img_h_max / z->img_comp[k].h; - r->vs = z->img_v_max / z->img_comp[k].v; - r->ystep = r->vs >> 1; - r->w_lores = (z->s->img_x + r->hs-1) / r->hs; - r->ypos = 0; - r->line0 = r->line1 = z->img_comp[k].data; + r->hs = z->img_h_max / z->img_comp[k].h; + r->vs = z->img_v_max / z->img_comp[k].v; + r->ystep = r->vs >> 1; + r->w_lores = (z->s->img_x + r->hs - 1) / r->hs; + r->ypos = 0; + r->line0 = r->line1 = z->img_comp[k].data; - if (r->hs == 1 && r->vs == 1) r->resample = resample_row_1; - else if (r->hs == 1 && r->vs == 2) r->resample = stbi__resample_row_v_2; - else if (r->hs == 2 && r->vs == 1) r->resample = stbi__resample_row_h_2; - else if (r->hs == 2 && r->vs == 2) r->resample = z->resample_row_hv_2_kernel; - else r->resample = stbi__resample_row_generic; + if (r->hs == 1 && r->vs == 1) + r->resample = resample_row_1; + else if (r->hs == 1 && r->vs == 2) + r->resample = stbi__resample_row_v_2; + else if (r->hs == 2 && r->vs == 1) + r->resample = stbi__resample_row_h_2; + else if (r->hs == 2 && r->vs == 2) + r->resample = z->resample_row_hv_2_kernel; + else + r->resample = stbi__resample_row_generic; } // can't error after this so, this is safe - output = (stbi_uc *) stbi__malloc_mad3(n, z->s->img_x, z->s->img_y, 1); - if (!output) { stbi__cleanup_jpeg(z); return stbi__errpuc("outofmem", "Out of memory"); } + output = (stbi_uc *)stbi__malloc_mad3(n, z->s->img_x, z->s->img_y, 1); + if (!output) + { + stbi__cleanup_jpeg(z); + return stbi__errpuc("outofmem", "Out of memory"); + } // now go ahead and resample - for (j=0; j < z->s->img_y; ++j) { + for (j = 0; j < z->s->img_y; ++j) + { stbi_uc *out = output + n * z->s->img_x * j; - for (k=0; k < decode_n; ++k) { + for (k = 0; k < decode_n; ++k) + { stbi__resample *r = &res_comp[k]; int y_bot = r->ystep >= (r->vs >> 1); coutput[k] = r->resample(z->img_comp[k].linebuf, y_bot ? r->line1 : r->line0, y_bot ? r->line0 : r->line1, r->w_lores, r->hs); - if (++r->ystep >= r->vs) { + if (++r->ystep >= r->vs) + { r->ystep = 0; r->line0 = r->line1; if (++r->ypos < z->img_comp[k].y) r->line1 += z->img_comp[k].w2; } } - if (n >= 3) { + if (n >= 3) + { stbi_uc *y = coutput[0]; - if (z->s->img_n == 3) { - if (is_rgb) { - for (i=0; i < z->s->img_x; ++i) { + if (z->s->img_n == 3) + { + if (is_rgb) + { + for (i = 0; i < z->s->img_x; ++i) + { out[0] = y[i]; out[1] = coutput[1][i]; out[2] = coutput[2][i]; out[3] = 255; out += n; } - } else { + } + else + { z->YCbCr_to_RGB_kernel(out, y, coutput[1], coutput[2], z->s->img_x, n); } - } else if (z->s->img_n == 4) { - if (z->app14_color_transform == 0) { // CMYK - for (i=0; i < z->s->img_x; ++i) { + } + else if (z->s->img_n == 4) + { + if (z->app14_color_transform == 0) + { // CMYK + for (i = 0; i < z->s->img_x; ++i) + { stbi_uc m = coutput[3][i]; out[0] = stbi__blinn_8x8(coutput[0][i], m); out[1] = stbi__blinn_8x8(coutput[1][i], m); @@ -3963,37 +4505,52 @@ static stbi_uc *load_jpeg_image(stbi__jpeg *z, int *out_x, int *out_y, int *comp out[3] = 255; out += n; } - } else if (z->app14_color_transform == 2) { // YCCK + } + else if (z->app14_color_transform == 2) + { // YCCK z->YCbCr_to_RGB_kernel(out, y, coutput[1], coutput[2], z->s->img_x, n); - for (i=0; i < z->s->img_x; ++i) { + for (i = 0; i < z->s->img_x; ++i) + { stbi_uc m = coutput[3][i]; out[0] = stbi__blinn_8x8(255 - out[0], m); out[1] = stbi__blinn_8x8(255 - out[1], m); out[2] = stbi__blinn_8x8(255 - out[2], m); out += n; } - } else { // YCbCr + alpha? Ignore the fourth channel for now + } + else + { // YCbCr + alpha? Ignore the fourth channel for now z->YCbCr_to_RGB_kernel(out, y, coutput[1], coutput[2], z->s->img_x, n); } - } else - for (i=0; i < z->s->img_x; ++i) { + } + else + for (i = 0; i < z->s->img_x; ++i) + { out[0] = out[1] = out[2] = y[i]; out[3] = 255; // not used if n==3 out += n; } - } else { - if (is_rgb) { + } + else + { + if (is_rgb) + { if (n == 1) - for (i=0; i < z->s->img_x; ++i) + for (i = 0; i < z->s->img_x; ++i) *out++ = stbi__compute_y(coutput[0][i], coutput[1][i], coutput[2][i]); - else { - for (i=0; i < z->s->img_x; ++i, out += 2) { + else + { + for (i = 0; i < z->s->img_x; ++i, out += 2) + { out[0] = stbi__compute_y(coutput[0][i], coutput[1][i], coutput[2][i]); out[1] = 255; } } - } else if (z->s->img_n == 4 && z->app14_color_transform == 0) { - for (i=0; i < z->s->img_x; ++i) { + } + else if (z->s->img_n == 4 && z->app14_color_transform == 0) + { + for (i = 0; i < z->s->img_x; ++i) + { stbi_uc m = coutput[3][i]; stbi_uc r = stbi__blinn_8x8(coutput[0][i], m); stbi_uc g = stbi__blinn_8x8(coutput[1][i], m); @@ -4002,39 +4559,51 @@ static stbi_uc *load_jpeg_image(stbi__jpeg *z, int *out_x, int *out_y, int *comp out[1] = 255; out += n; } - } else if (z->s->img_n == 4 && z->app14_color_transform == 2) { - for (i=0; i < z->s->img_x; ++i) { + } + else if (z->s->img_n == 4 && z->app14_color_transform == 2) + { + for (i = 0; i < z->s->img_x; ++i) + { out[0] = stbi__blinn_8x8(255 - coutput[0][i], coutput[3][i]); out[1] = 255; out += n; } - } else { + } + else + { stbi_uc *y = coutput[0]; if (n == 1) - for (i=0; i < z->s->img_x; ++i) out[i] = y[i]; + for (i = 0; i < z->s->img_x; ++i) + out[i] = y[i]; else - for (i=0; i < z->s->img_x; ++i) { *out++ = y[i]; *out++ = 255; } + for (i = 0; i < z->s->img_x; ++i) + { + *out++ = y[i]; + *out++ = 255; + } } } } stbi__cleanup_jpeg(z); *out_x = z->s->img_x; *out_y = z->s->img_y; - if (comp) *comp = z->s->img_n >= 3 ? 3 : 1; // report original components, not output + if (comp) + *comp = z->s->img_n >= 3 ? 3 : 1; // report original components, not output return output; } } static void *stbi__jpeg_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri) { - unsigned char* result; - stbi__jpeg* j = (stbi__jpeg*) stbi__malloc(sizeof(stbi__jpeg)); - if (!j) return stbi__errpuc("outofmem", "Out of memory"); + unsigned char *result; + stbi__jpeg *j = (stbi__jpeg *)stbi__malloc(sizeof(stbi__jpeg)); + if (!j) + return stbi__errpuc("outofmem", "Out of memory"); memset(j, 0, sizeof(stbi__jpeg)); STBI_NOTUSED(ri); j->s = s; stbi__setup_jpeg(j); - result = load_jpeg_image(j, x,y,comp,req_comp); + result = load_jpeg_image(j, x, y, comp, req_comp); STBI_FREE(j); return result; } @@ -4042,8 +4611,9 @@ static void *stbi__jpeg_load(stbi__context *s, int *x, int *y, int *comp, int re static int stbi__jpeg_test(stbi__context *s) { int r; - stbi__jpeg* j = (stbi__jpeg*)stbi__malloc(sizeof(stbi__jpeg)); - if (!j) return stbi__err("outofmem", "Out of memory"); + stbi__jpeg *j = (stbi__jpeg *)stbi__malloc(sizeof(stbi__jpeg)); + if (!j) + return stbi__err("outofmem", "Out of memory"); memset(j, 0, sizeof(stbi__jpeg)); j->s = s; stbi__setup_jpeg(j); @@ -4055,21 +4625,26 @@ static int stbi__jpeg_test(stbi__context *s) static int stbi__jpeg_info_raw(stbi__jpeg *j, int *x, int *y, int *comp) { - if (!stbi__decode_jpeg_header(j, STBI__SCAN_header)) { - stbi__rewind( j->s ); + if (!stbi__decode_jpeg_header(j, STBI__SCAN_header)) + { + stbi__rewind(j->s); return 0; } - if (x) *x = j->s->img_x; - if (y) *y = j->s->img_y; - if (comp) *comp = j->s->img_n >= 3 ? 3 : 1; + if (x) + *x = j->s->img_x; + if (y) + *y = j->s->img_y; + if (comp) + *comp = j->s->img_n >= 3 ? 3 : 1; return 1; } static int stbi__jpeg_info(stbi__context *s, int *x, int *y, int *comp) { int result; - stbi__jpeg* j = (stbi__jpeg*) (stbi__malloc(sizeof(stbi__jpeg))); - if (!j) return stbi__err("outofmem", "Out of memory"); + stbi__jpeg *j = (stbi__jpeg *)(stbi__malloc(sizeof(stbi__jpeg))); + if (!j) + return stbi__err("outofmem", "Out of memory"); memset(j, 0, sizeof(stbi__jpeg)); j->s = s; result = stbi__jpeg_info_raw(j, x, y, comp); @@ -4088,8 +4663,8 @@ static int stbi__jpeg_info(stbi__context *s, int *x, int *y, int *comp) #ifndef STBI_NO_ZLIB // fast-way is faster to check than jpeg huffman, but slow way is slower -#define STBI__ZFAST_BITS 9 // accelerate all cases in default tables -#define STBI__ZFAST_MASK ((1 << STBI__ZFAST_BITS) - 1) +#define STBI__ZFAST_BITS 9 // accelerate all cases in default tables +#define STBI__ZFAST_MASK ((1 << STBI__ZFAST_BITS) - 1) #define STBI__ZNSYMS 288 // number of symbols in literal/length alphabet // zlib-style huffman encoding @@ -4100,17 +4675,17 @@ typedef struct stbi__uint16 firstcode[16]; int maxcode[17]; stbi__uint16 firstsymbol[16]; - stbi_uc size[STBI__ZNSYMS]; + stbi_uc size[STBI__ZNSYMS]; stbi__uint16 value[STBI__ZNSYMS]; } stbi__zhuffman; stbi_inline static int stbi__bitreverse16(int n) { - n = ((n & 0xAAAA) >> 1) | ((n & 0x5555) << 1); - n = ((n & 0xCCCC) >> 2) | ((n & 0x3333) << 2); - n = ((n & 0xF0F0) >> 4) | ((n & 0x0F0F) << 4); - n = ((n & 0xFF00) >> 8) | ((n & 0x00FF) << 8); - return n; + n = ((n & 0xAAAA) >> 1) | ((n & 0x5555) << 1); + n = ((n & 0xCCCC) >> 2) | ((n & 0x3333) << 2); + n = ((n & 0xF0F0) >> 4) | ((n & 0x0F0F) << 4); + n = ((n & 0xFF00) >> 8) | ((n & 0x00FF) << 8); + return n; } stbi_inline static int stbi__bit_reverse(int v, int bits) @@ -4118,46 +4693,52 @@ stbi_inline static int stbi__bit_reverse(int v, int bits) STBI_ASSERT(bits <= 16); // to bit reverse n bits, reverse 16 and shift // e.g. 11 bits, bit reverse and shift away 5 - return stbi__bitreverse16(v) >> (16-bits); + return stbi__bitreverse16(v) >> (16 - bits); } static int stbi__zbuild_huffman(stbi__zhuffman *z, const stbi_uc *sizelist, int num) { - int i,k=0; + int i, k = 0; int code, next_code[16], sizes[17]; // DEFLATE spec for generating codes memset(sizes, 0, sizeof(sizes)); memset(z->fast, 0, sizeof(z->fast)); - for (i=0; i < num; ++i) + for (i = 0; i < num; ++i) ++sizes[sizelist[i]]; sizes[0] = 0; - for (i=1; i < 16; ++i) + for (i = 1; i < 16; ++i) if (sizes[i] > (1 << i)) return stbi__err("bad sizes", "Corrupt PNG"); code = 0; - for (i=1; i < 16; ++i) { + for (i = 1; i < 16; ++i) + { next_code[i] = code; - z->firstcode[i] = (stbi__uint16) code; - z->firstsymbol[i] = (stbi__uint16) k; + z->firstcode[i] = (stbi__uint16)code; + z->firstsymbol[i] = (stbi__uint16)k; code = (code + sizes[i]); if (sizes[i]) - if (code-1 >= (1 << i)) return stbi__err("bad codelengths","Corrupt PNG"); - z->maxcode[i] = code << (16-i); // preshift for inner loop + if (code - 1 >= (1 << i)) + return stbi__err("bad codelengths", "Corrupt PNG"); + z->maxcode[i] = code << (16 - i); // preshift for inner loop code <<= 1; k += sizes[i]; } z->maxcode[16] = 0x10000; // sentinel - for (i=0; i < num; ++i) { + for (i = 0; i < num; ++i) + { int s = sizelist[i]; - if (s) { + if (s) + { int c = next_code[s] - z->firstcode[s] + z->firstsymbol[s]; - stbi__uint16 fastv = (stbi__uint16) ((s << 9) | i); - z->size [c] = (stbi_uc ) s; - z->value[c] = (stbi__uint16) i; - if (s <= STBI__ZFAST_BITS) { - int j = stbi__bit_reverse(next_code[s],s); - while (j < (1 << STBI__ZFAST_BITS)) { + stbi__uint16 fastv = (stbi__uint16)((s << 9) | i); + z->size[c] = (stbi_uc)s; + z->value[c] = (stbi__uint16)i; + if (s <= STBI__ZFAST_BITS) + { + int j = stbi__bit_reverse(next_code[s], s); + while (j < (1 << STBI__ZFAST_BITS)) + { z->fast[j] = fastv; j += (1 << s); } @@ -4184,7 +4765,7 @@ typedef struct char *zout; char *zout_start; char *zout_end; - int z_expandable; + int z_expandable; stbi__zhuffman z_length, z_distance; } stbi__zbuf; @@ -4201,12 +4782,14 @@ stbi_inline static stbi_uc stbi__zget8(stbi__zbuf *z) static void stbi__fill_bits(stbi__zbuf *z) { - do { - if (z->code_buffer >= (1U << z->num_bits)) { - z->zbuffer = z->zbuffer_end; /* treat this as EOF so we fail. */ - return; + do + { + if (z->code_buffer >= (1U << z->num_bits)) + { + z->zbuffer = z->zbuffer_end; /* treat this as EOF so we fail. */ + return; } - z->code_buffer |= (unsigned int) stbi__zget8(z) << z->num_bits; + z->code_buffer |= (unsigned int)stbi__zget8(z) << z->num_bits; z->num_bits += 8; } while (z->num_bits <= 24); } @@ -4214,7 +4797,8 @@ static void stbi__fill_bits(stbi__zbuf *z) stbi_inline static unsigned int stbi__zreceive(stbi__zbuf *z, int n) { unsigned int k; - if (z->num_bits < n) stbi__fill_bits(z); + if (z->num_bits < n) + stbi__fill_bits(z); k = z->code_buffer & ((1 << n) - 1); z->code_buffer >>= n; z->num_bits -= n; @@ -4223,18 +4807,21 @@ stbi_inline static unsigned int stbi__zreceive(stbi__zbuf *z, int n) static int stbi__zhuffman_decode_slowpath(stbi__zbuf *a, stbi__zhuffman *z) { - int b,s,k; + int b, s, k; // not resolved by fast table, so compute it the slow way // use jpeg approach, which requires MSbits at top k = stbi__bit_reverse(a->code_buffer, 16); - for (s=STBI__ZFAST_BITS+1; ; ++s) + for (s = STBI__ZFAST_BITS + 1;; ++s) if (k < z->maxcode[s]) break; - if (s >= 16) return -1; // invalid code! + if (s >= 16) + return -1; // invalid code! // code size is s, so: - b = (k >> (16-s)) - z->firstcode[s] + z->firstsymbol[s]; - if (b >= STBI__ZNSYMS) return -1; // some data was corrupt somewhere! - if (z->size[b] != s) return -1; // was originally an assert, but report failure instead. + b = (k >> (16 - s)) - z->firstcode[s] + z->firstsymbol[s]; + if (b >= STBI__ZNSYMS) + return -1; // some data was corrupt somewhere! + if (z->size[b] != s) + return -1; // was originally an assert, but report failure instead. a->code_buffer >>= s; a->num_bits -= s; return z->value[b]; @@ -4242,26 +4829,34 @@ static int stbi__zhuffman_decode_slowpath(stbi__zbuf *a, stbi__zhuffman *z) stbi_inline static int stbi__zhuffman_decode(stbi__zbuf *a, stbi__zhuffman *z) { - int b,s; - if (a->num_bits < 16) { - if (stbi__zeof(a)) { - if (!a->hit_zeof_once) { + int b, s; + if (a->num_bits < 16) + { + if (stbi__zeof(a)) + { + if (!a->hit_zeof_once) + { // This is the first time we hit eof, insert 16 extra padding btis // to allow us to keep going; if we actually consume any of them // though, that is invalid data. This is caught later. a->hit_zeof_once = 1; a->num_bits += 16; // add 16 implicit zero bits - } else { + } + else + { // We already inserted our extra 16 padding bits and are again // out, this stream is actually prematurely terminated. return -1; } - } else { + } + else + { stbi__fill_bits(a); } } b = z->fast[a->code_buffer & STBI__ZFAST_MASK]; - if (b) { + if (b) + { s = b >> 9; a->code_buffer >>= s; a->num_bits -= s; @@ -4270,87 +4865,121 @@ stbi_inline static int stbi__zhuffman_decode(stbi__zbuf *a, stbi__zhuffman *z) return stbi__zhuffman_decode_slowpath(a, z); } -static int stbi__zexpand(stbi__zbuf *z, char *zout, int n) // need to make room for n bytes +static int stbi__zexpand(stbi__zbuf *z, char *zout, int n) // need to make room for n bytes { char *q; unsigned int cur, limit, old_limit; z->zout = zout; - if (!z->z_expandable) return stbi__err("output buffer limit","Corrupt PNG"); - cur = (unsigned int) (z->zout - z->zout_start); - limit = old_limit = (unsigned) (z->zout_end - z->zout_start); - if (UINT_MAX - cur < (unsigned) n) return stbi__err("outofmem", "Out of memory"); - while (cur + n > limit) { - if(limit > UINT_MAX / 2) return stbi__err("outofmem", "Out of memory"); + if (!z->z_expandable) + return stbi__err("output buffer limit", "Corrupt PNG"); + cur = (unsigned int)(z->zout - z->zout_start); + limit = old_limit = (unsigned)(z->zout_end - z->zout_start); + if (UINT_MAX - cur < (unsigned)n) + return stbi__err("outofmem", "Out of memory"); + while (cur + n > limit) + { + if (limit > UINT_MAX / 2) + return stbi__err("outofmem", "Out of memory"); limit *= 2; } - q = (char *) STBI_REALLOC_SIZED(z->zout_start, old_limit, limit); + q = (char *)STBI_REALLOC_SIZED(z->zout_start, old_limit, limit); STBI_NOTUSED(old_limit); - if (q == NULL) return stbi__err("outofmem", "Out of memory"); + if (q == NULL) + return stbi__err("outofmem", "Out of memory"); z->zout_start = q; - z->zout = q + cur; - z->zout_end = q + limit; + z->zout = q + cur; + z->zout_end = q + limit; return 1; } static const int stbi__zlength_base[31] = { - 3,4,5,6,7,8,9,10,11,13, - 15,17,19,23,27,31,35,43,51,59, - 67,83,99,115,131,163,195,227,258,0,0 }; + 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, + 15, 17, 19, 23, 27, 31, 35, 43, 51, 59, + 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0}; -static const int stbi__zlength_extra[31]= -{ 0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0,0,0 }; +static const int stbi__zlength_extra[31] = + {0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 0, 0}; -static const int stbi__zdist_base[32] = { 1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193, -257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577,0,0}; +static const int stbi__zdist_base[32] = {1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, + 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577, 0, 0}; static const int stbi__zdist_extra[32] = -{ 0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13}; + {0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13}; static int stbi__parse_huffman_block(stbi__zbuf *a) { char *zout = a->zout; - for(;;) { + for (;;) + { int z = stbi__zhuffman_decode(a, &a->z_length); - if (z < 256) { - if (z < 0) return stbi__err("bad huffman code","Corrupt PNG"); // error in huffman codes - if (zout >= a->zout_end) { - if (!stbi__zexpand(a, zout, 1)) return 0; + if (z < 256) + { + if (z < 0) + return stbi__err("bad huffman code", "Corrupt PNG"); // error in huffman codes + if (zout >= a->zout_end) + { + if (!stbi__zexpand(a, zout, 1)) + return 0; zout = a->zout; } - *zout++ = (char) z; - } else { + *zout++ = (char)z; + } + else + { stbi_uc *p; - int len,dist; - if (z == 256) { + int len, dist; + if (z == 256) + { a->zout = zout; - if (a->hit_zeof_once && a->num_bits < 16) { + if (a->hit_zeof_once && a->num_bits < 16) + { // The first time we hit zeof, we inserted 16 extra zero bits into our bit // buffer so the decoder can just do its speculative decoding. But if we // actually consumed any of those bits (which is the case when num_bits < 16), // the stream actually read past the end so it is malformed. - return stbi__err("unexpected end","Corrupt PNG"); + return stbi__err("unexpected end", "Corrupt PNG"); } return 1; } - if (z >= 286) return stbi__err("bad huffman code","Corrupt PNG"); // per DEFLATE, length codes 286 and 287 must not appear in compressed data + if (z >= 286) + return stbi__err("bad huffman code", "Corrupt PNG"); // per DEFLATE, length codes 286 and 287 must not appear in compressed data z -= 257; len = stbi__zlength_base[z]; - if (stbi__zlength_extra[z]) len += stbi__zreceive(a, stbi__zlength_extra[z]); + if (stbi__zlength_extra[z]) + len += stbi__zreceive(a, stbi__zlength_extra[z]); z = stbi__zhuffman_decode(a, &a->z_distance); - if (z < 0 || z >= 30) return stbi__err("bad huffman code","Corrupt PNG"); // per DEFLATE, distance codes 30 and 31 must not appear in compressed data + if (z < 0 || z >= 30) + return stbi__err("bad huffman code", "Corrupt PNG"); // per DEFLATE, distance codes 30 and 31 must not appear in compressed data dist = stbi__zdist_base[z]; - if (stbi__zdist_extra[z]) dist += stbi__zreceive(a, stbi__zdist_extra[z]); - if (zout - a->zout_start < dist) return stbi__err("bad dist","Corrupt PNG"); - if (len > a->zout_end - zout) { - if (!stbi__zexpand(a, zout, len)) return 0; + if (stbi__zdist_extra[z]) + dist += stbi__zreceive(a, stbi__zdist_extra[z]); + if (zout - a->zout_start < dist) + return stbi__err("bad dist", "Corrupt PNG"); + if (len > a->zout_end - zout) + { + if (!stbi__zexpand(a, zout, len)) + return 0; zout = a->zout; } - p = (stbi_uc *) (zout - dist); - if (dist == 1) { // run of one byte; common in images. + p = (stbi_uc *)(zout - dist); + if (dist == 1) + { // run of one byte; common in images. stbi_uc v = *p; - if (len) { do *zout++ = v; while (--len); } - } else { - if (len) { do *zout++ = *p++; while (--len); } + if (len) + { + do + *zout++ = v; + while (--len); + } + } + else + { + if (len) + { + do + *zout++ = *p++; + while (--len); + } } } } @@ -4358,77 +4987,99 @@ static int stbi__parse_huffman_block(stbi__zbuf *a) static int stbi__compute_huffman_codes(stbi__zbuf *a) { - static const stbi_uc length_dezigzag[19] = { 16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15 }; + static const stbi_uc length_dezigzag[19] = {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; stbi__zhuffman z_codelength; - stbi_uc lencodes[286+32+137];//padding for maximum single op + stbi_uc lencodes[286 + 32 + 137]; // padding for maximum single op stbi_uc codelength_sizes[19]; - int i,n; + int i, n; - int hlit = stbi__zreceive(a,5) + 257; - int hdist = stbi__zreceive(a,5) + 1; - int hclen = stbi__zreceive(a,4) + 4; - int ntot = hlit + hdist; + int hlit = stbi__zreceive(a, 5) + 257; + int hdist = stbi__zreceive(a, 5) + 1; + int hclen = stbi__zreceive(a, 4) + 4; + int ntot = hlit + hdist; memset(codelength_sizes, 0, sizeof(codelength_sizes)); - for (i=0; i < hclen; ++i) { - int s = stbi__zreceive(a,3); - codelength_sizes[length_dezigzag[i]] = (stbi_uc) s; + for (i = 0; i < hclen; ++i) + { + int s = stbi__zreceive(a, 3); + codelength_sizes[length_dezigzag[i]] = (stbi_uc)s; } - if (!stbi__zbuild_huffman(&z_codelength, codelength_sizes, 19)) return 0; + if (!stbi__zbuild_huffman(&z_codelength, codelength_sizes, 19)) + return 0; n = 0; - while (n < ntot) { + while (n < ntot) + { int c = stbi__zhuffman_decode(a, &z_codelength); - if (c < 0 || c >= 19) return stbi__err("bad codelengths", "Corrupt PNG"); + if (c < 0 || c >= 19) + return stbi__err("bad codelengths", "Corrupt PNG"); if (c < 16) - lencodes[n++] = (stbi_uc) c; - else { + lencodes[n++] = (stbi_uc)c; + else + { stbi_uc fill = 0; - if (c == 16) { - c = stbi__zreceive(a,2)+3; - if (n == 0) return stbi__err("bad codelengths", "Corrupt PNG"); - fill = lencodes[n-1]; - } else if (c == 17) { - c = stbi__zreceive(a,3)+3; - } else if (c == 18) { - c = stbi__zreceive(a,7)+11; - } else { + if (c == 16) + { + c = stbi__zreceive(a, 2) + 3; + if (n == 0) + return stbi__err("bad codelengths", "Corrupt PNG"); + fill = lencodes[n - 1]; + } + else if (c == 17) + { + c = stbi__zreceive(a, 3) + 3; + } + else if (c == 18) + { + c = stbi__zreceive(a, 7) + 11; + } + else + { return stbi__err("bad codelengths", "Corrupt PNG"); } - if (ntot - n < c) return stbi__err("bad codelengths", "Corrupt PNG"); - memset(lencodes+n, fill, c); + if (ntot - n < c) + return stbi__err("bad codelengths", "Corrupt PNG"); + memset(lencodes + n, fill, c); n += c; } } - if (n != ntot) return stbi__err("bad codelengths","Corrupt PNG"); - if (!stbi__zbuild_huffman(&a->z_length, lencodes, hlit)) return 0; - if (!stbi__zbuild_huffman(&a->z_distance, lencodes+hlit, hdist)) return 0; + if (n != ntot) + return stbi__err("bad codelengths", "Corrupt PNG"); + if (!stbi__zbuild_huffman(&a->z_length, lencodes, hlit)) + return 0; + if (!stbi__zbuild_huffman(&a->z_distance, lencodes + hlit, hdist)) + return 0; return 1; } static int stbi__parse_uncompressed_block(stbi__zbuf *a) { stbi_uc header[4]; - int len,nlen,k; + int len, nlen, k; if (a->num_bits & 7) stbi__zreceive(a, a->num_bits & 7); // discard // drain the bit-packed data into header k = 0; - while (a->num_bits > 0) { - header[k++] = (stbi_uc) (a->code_buffer & 255); // suppress MSVC run-time check + while (a->num_bits > 0) + { + header[k++] = (stbi_uc)(a->code_buffer & 255); // suppress MSVC run-time check a->code_buffer >>= 8; a->num_bits -= 8; } - if (a->num_bits < 0) return stbi__err("zlib corrupt","Corrupt PNG"); + if (a->num_bits < 0) + return stbi__err("zlib corrupt", "Corrupt PNG"); // now fill header the normal way while (k < 4) header[k++] = stbi__zget8(a); - len = header[1] * 256 + header[0]; + len = header[1] * 256 + header[0]; nlen = header[3] * 256 + header[2]; - if (nlen != (len ^ 0xffff)) return stbi__err("zlib corrupt","Corrupt PNG"); - if (a->zbuffer + len > a->zbuffer_end) return stbi__err("read past buffer","Corrupt PNG"); + if (nlen != (len ^ 0xffff)) + return stbi__err("zlib corrupt", "Corrupt PNG"); + if (a->zbuffer + len > a->zbuffer_end) + return stbi__err("read past buffer", "Corrupt PNG"); if (a->zout + len > a->zout_end) - if (!stbi__zexpand(a, a->zout, len)) return 0; + if (!stbi__zexpand(a, a->zout, len)) + return 0; memcpy(a->zout, a->zbuffer, len); a->zbuffer += len; a->zout += len; @@ -4437,34 +5088,36 @@ static int stbi__parse_uncompressed_block(stbi__zbuf *a) static int stbi__parse_zlib_header(stbi__zbuf *a) { - int cmf = stbi__zget8(a); - int cm = cmf & 15; + int cmf = stbi__zget8(a); + int cm = cmf & 15; /* int cinfo = cmf >> 4; */ - int flg = stbi__zget8(a); - if (stbi__zeof(a)) return stbi__err("bad zlib header","Corrupt PNG"); // zlib spec - if ((cmf*256+flg) % 31 != 0) return stbi__err("bad zlib header","Corrupt PNG"); // zlib spec - if (flg & 32) return stbi__err("no preset dict","Corrupt PNG"); // preset dictionary not allowed in png - if (cm != 8) return stbi__err("bad compression","Corrupt PNG"); // DEFLATE required for png + int flg = stbi__zget8(a); + if (stbi__zeof(a)) + return stbi__err("bad zlib header", "Corrupt PNG"); // zlib spec + if ((cmf * 256 + flg) % 31 != 0) + return stbi__err("bad zlib header", "Corrupt PNG"); // zlib spec + if (flg & 32) + return stbi__err("no preset dict", "Corrupt PNG"); // preset dictionary not allowed in png + if (cm != 8) + return stbi__err("bad compression", "Corrupt PNG"); // DEFLATE required for png // window = 1 << (8 + cinfo)... but who cares, we fully buffer output return 1; } static const stbi_uc stbi__zdefault_length[STBI__ZNSYMS] = -{ - 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, - 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, - 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, - 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, - 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, - 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, - 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, - 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, - 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, 7,7,7,7,7,7,7,7,8,8,8,8,8,8,8,8 -}; + { + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8}; static const stbi_uc stbi__zdefault_distance[32] = -{ - 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5 -}; + { + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5}; /* Init algorithm: { @@ -4482,26 +5135,41 @@ static int stbi__parse_zlib(stbi__zbuf *a, int parse_header) { int final, type; if (parse_header) - if (!stbi__parse_zlib_header(a)) return 0; + if (!stbi__parse_zlib_header(a)) + return 0; a->num_bits = 0; a->code_buffer = 0; a->hit_zeof_once = 0; - do { - final = stbi__zreceive(a,1); - type = stbi__zreceive(a,2); - if (type == 0) { - if (!stbi__parse_uncompressed_block(a)) return 0; - } else if (type == 3) { + do + { + final = stbi__zreceive(a, 1); + type = stbi__zreceive(a, 2); + if (type == 0) + { + if (!stbi__parse_uncompressed_block(a)) + return 0; + } + else if (type == 3) + { return 0; - } else { - if (type == 1) { + } + else + { + if (type == 1) + { // use fixed code lengths - if (!stbi__zbuild_huffman(&a->z_length , stbi__zdefault_length , STBI__ZNSYMS)) return 0; - if (!stbi__zbuild_huffman(&a->z_distance, stbi__zdefault_distance, 32)) return 0; - } else { - if (!stbi__compute_huffman_codes(a)) return 0; + if (!stbi__zbuild_huffman(&a->z_length, stbi__zdefault_length, STBI__ZNSYMS)) + return 0; + if (!stbi__zbuild_huffman(&a->z_distance, stbi__zdefault_distance, 32)) + return 0; } - if (!stbi__parse_huffman_block(a)) return 0; + else + { + if (!stbi__compute_huffman_codes(a)) + return 0; + } + if (!stbi__parse_huffman_block(a)) + return 0; } } while (!final); return 1; @@ -4510,8 +5178,8 @@ static int stbi__parse_zlib(stbi__zbuf *a, int parse_header) static int stbi__do_zlib(stbi__zbuf *a, char *obuf, int olen, int exp, int parse_header) { a->zout_start = obuf; - a->zout = obuf; - a->zout_end = obuf + olen; + a->zout = obuf; + a->zout_end = obuf + olen; a->z_expandable = exp; return stbi__parse_zlib(a, parse_header); @@ -4520,14 +5188,19 @@ static int stbi__do_zlib(stbi__zbuf *a, char *obuf, int olen, int exp, int parse STBIDEF char *stbi_zlib_decode_malloc_guesssize(const char *buffer, int len, int initial_size, int *outlen) { stbi__zbuf a; - char *p = (char *) stbi__malloc(initial_size); - if (p == NULL) return NULL; - a.zbuffer = (stbi_uc *) buffer; - a.zbuffer_end = (stbi_uc *) buffer + len; - if (stbi__do_zlib(&a, p, initial_size, 1, 1)) { - if (outlen) *outlen = (int) (a.zout - a.zout_start); + char *p = (char *)stbi__malloc(initial_size); + if (p == NULL) + return NULL; + a.zbuffer = (stbi_uc *)buffer; + a.zbuffer_end = (stbi_uc *)buffer + len; + if (stbi__do_zlib(&a, p, initial_size, 1, 1)) + { + if (outlen) + *outlen = (int)(a.zout - a.zout_start); return a.zout_start; - } else { + } + else + { STBI_FREE(a.zout_start); return NULL; } @@ -4541,14 +5214,19 @@ STBIDEF char *stbi_zlib_decode_malloc(char const *buffer, int len, int *outlen) STBIDEF char *stbi_zlib_decode_malloc_guesssize_headerflag(const char *buffer, int len, int initial_size, int *outlen, int parse_header) { stbi__zbuf a; - char *p = (char *) stbi__malloc(initial_size); - if (p == NULL) return NULL; - a.zbuffer = (stbi_uc *) buffer; - a.zbuffer_end = (stbi_uc *) buffer + len; - if (stbi__do_zlib(&a, p, initial_size, 1, parse_header)) { - if (outlen) *outlen = (int) (a.zout - a.zout_start); + char *p = (char *)stbi__malloc(initial_size); + if (p == NULL) + return NULL; + a.zbuffer = (stbi_uc *)buffer; + a.zbuffer_end = (stbi_uc *)buffer + len; + if (stbi__do_zlib(&a, p, initial_size, 1, parse_header)) + { + if (outlen) + *outlen = (int)(a.zout - a.zout_start); return a.zout_start; - } else { + } + else + { STBI_FREE(a.zout_start); return NULL; } @@ -4557,10 +5235,10 @@ STBIDEF char *stbi_zlib_decode_malloc_guesssize_headerflag(const char *buffer, i STBIDEF int stbi_zlib_decode_buffer(char *obuffer, int olen, char const *ibuffer, int ilen) { stbi__zbuf a; - a.zbuffer = (stbi_uc *) ibuffer; - a.zbuffer_end = (stbi_uc *) ibuffer + ilen; + a.zbuffer = (stbi_uc *)ibuffer; + a.zbuffer_end = (stbi_uc *)ibuffer + ilen; if (stbi__do_zlib(&a, obuffer, olen, 0, 1)) - return (int) (a.zout - a.zout_start); + return (int)(a.zout - a.zout_start); else return -1; } @@ -4568,14 +5246,19 @@ STBIDEF int stbi_zlib_decode_buffer(char *obuffer, int olen, char const *ibuffer STBIDEF char *stbi_zlib_decode_noheader_malloc(char const *buffer, int len, int *outlen) { stbi__zbuf a; - char *p = (char *) stbi__malloc(16384); - if (p == NULL) return NULL; - a.zbuffer = (stbi_uc *) buffer; - a.zbuffer_end = (stbi_uc *) buffer+len; - if (stbi__do_zlib(&a, p, 16384, 1, 0)) { - if (outlen) *outlen = (int) (a.zout - a.zout_start); + char *p = (char *)stbi__malloc(16384); + if (p == NULL) + return NULL; + a.zbuffer = (stbi_uc *)buffer; + a.zbuffer_end = (stbi_uc *)buffer + len; + if (stbi__do_zlib(&a, p, 16384, 1, 0)) + { + if (outlen) + *outlen = (int)(a.zout - a.zout_start); return a.zout_start; - } else { + } + else + { STBI_FREE(a.zout_start); return NULL; } @@ -4584,10 +5267,10 @@ STBIDEF char *stbi_zlib_decode_noheader_malloc(char const *buffer, int len, int STBIDEF int stbi_zlib_decode_noheader_buffer(char *obuffer, int olen, const char *ibuffer, int ilen) { stbi__zbuf a; - a.zbuffer = (stbi_uc *) ibuffer; - a.zbuffer_end = (stbi_uc *) ibuffer + ilen; + a.zbuffer = (stbi_uc *)ibuffer; + a.zbuffer_end = (stbi_uc *)ibuffer + ilen; if (stbi__do_zlib(&a, obuffer, olen, 0, 0)) - return (int) (a.zout - a.zout_start); + return (int)(a.zout - a.zout_start); else return -1; } @@ -4614,16 +5297,17 @@ static stbi__pngchunk stbi__get_chunk_header(stbi__context *s) { stbi__pngchunk c; c.length = stbi__get32be(s); - c.type = stbi__get32be(s); + c.type = stbi__get32be(s); return c; } static int stbi__check_png_header(stbi__context *s) { - static const stbi_uc png_sig[8] = { 137,80,78,71,13,10,26,10 }; + static const stbi_uc png_sig[8] = {137, 80, 78, 71, 13, 10, 26, 10}; int i; - for (i=0; i < 8; ++i) - if (stbi__get8(s) != png_sig[i]) return stbi__err("bad png sig","Not a PNG"); + for (i = 0; i < 8; ++i) + if (stbi__get8(s) != png_sig[i]) + return stbi__err("bad png sig", "Not a PNG"); return 1; } @@ -4634,24 +5318,24 @@ typedef struct int depth; } stbi__png; - -enum { - STBI__F_none=0, - STBI__F_sub=1, - STBI__F_up=2, - STBI__F_avg=3, - STBI__F_paeth=4, +enum +{ + STBI__F_none = 0, + STBI__F_sub = 1, + STBI__F_up = 2, + STBI__F_avg = 3, + STBI__F_paeth = 4, // synthetic filter used for first scanline to avoid needing a dummy row of 0s STBI__F_avg_first }; static stbi_uc first_row_filter[5] = -{ - STBI__F_none, - STBI__F_sub, - STBI__F_none, - STBI__F_avg_first, - STBI__F_sub // Paeth with b=c=0 turns out to be equivalent to sub + { + STBI__F_none, + STBI__F_sub, + STBI__F_none, + STBI__F_avg_first, + STBI__F_sub // Paeth with b=c=0 turns out to be equivalent to sub }; static int stbi__paeth(int a, int b, int c) @@ -4659,7 +5343,7 @@ static int stbi__paeth(int a, int b, int c) // This formulation looks very different from the reference in the PNG spec, but is // actually equivalent and has favorable data dependencies and admits straightforward // generation of branch-free code, which helps performance significantly. - int thresh = c*3 - (a + b); + int thresh = c * 3 - (a + b); int lo = a < b ? a : b; int hi = a < b ? b : a; int t0 = (hi <= thresh) ? lo : c; @@ -4667,7 +5351,7 @@ static int stbi__paeth(int a, int b, int c) return t1; } -static const stbi_uc stbi__depth_scale_table[9] = { 0, 0xff, 0x55, 0, 0x11, 0,0,0, 0x01 }; +static const stbi_uc stbi__depth_scale_table[9] = {0, 0xff, 0x55, 0, 0x11, 0, 0, 0, 0x01}; // adds an extra all-255 alpha channel // dest == src is legal @@ -4676,18 +5360,23 @@ static void stbi__create_png_alpha_expand8(stbi_uc *dest, stbi_uc *src, stbi__ui { int i; // must process data backwards since we allow dest==src - if (img_n == 1) { - for (i=x-1; i >= 0; --i) { - dest[i*2+1] = 255; - dest[i*2+0] = src[i]; + if (img_n == 1) + { + for (i = x - 1; i >= 0; --i) + { + dest[i * 2 + 1] = 255; + dest[i * 2 + 0] = src[i]; } - } else { + } + else + { STBI_ASSERT(img_n == 3); - for (i=x-1; i >= 0; --i) { - dest[i*4+3] = 255; - dest[i*4+2] = src[i*3+2]; - dest[i*4+1] = src[i*3+1]; - dest[i*4+0] = src[i*3+0]; + for (i = x - 1; i >= 0; --i) + { + dest[i * 4 + 3] = 255; + dest[i * 4 + 2] = src[i * 3 + 2]; + dest[i * 4 + 1] = src[i * 3 + 1]; + dest[i * 4 + 0] = src[i * 3 + 0]; } } } @@ -4697,69 +5386,79 @@ static int stbi__create_png_image_raw(stbi__png *a, stbi_uc *raw, stbi__uint32 r { int bytes = (depth == 16 ? 2 : 1); stbi__context *s = a->s; - stbi__uint32 i,j,stride = x*out_n*bytes; + stbi__uint32 i, j, stride = x * out_n * bytes; stbi__uint32 img_len, img_width_bytes; stbi_uc *filter_buf; int all_ok = 1; int k; int img_n = s->img_n; // copy it into a local for later - int output_bytes = out_n*bytes; - int filter_bytes = img_n*bytes; + int output_bytes = out_n * bytes; + int filter_bytes = img_n * bytes; int width = x; - STBI_ASSERT(out_n == s->img_n || out_n == s->img_n+1); - a->out = (stbi_uc *) stbi__malloc_mad3(x, y, output_bytes, 0); // extra bytes to write off the end into - if (!a->out) return stbi__err("outofmem", "Out of memory"); + STBI_ASSERT(out_n == s->img_n || out_n == s->img_n + 1); + a->out = (stbi_uc *)stbi__malloc_mad3(x, y, output_bytes, 0); // extra bytes to write off the end into + if (!a->out) + return stbi__err("outofmem", "Out of memory"); // note: error exits here don't need to clean up a->out individually, // stbi__do_png always does on error. - if (!stbi__mad3sizes_valid(img_n, x, depth, 7)) return stbi__err("too large", "Corrupt PNG"); + if (!stbi__mad3sizes_valid(img_n, x, depth, 7)) + return stbi__err("too large", "Corrupt PNG"); img_width_bytes = (((img_n * x * depth) + 7) >> 3); - if (!stbi__mad2sizes_valid(img_width_bytes, y, img_width_bytes)) return stbi__err("too large", "Corrupt PNG"); + if (!stbi__mad2sizes_valid(img_width_bytes, y, img_width_bytes)) + return stbi__err("too large", "Corrupt PNG"); img_len = (img_width_bytes + 1) * y; // we used to check for exact match between raw_len and img_len on non-interlaced PNGs, // but issue #276 reported a PNG in the wild that had extra data at the end (all zeros), // so just check for raw_len < img_len always. - if (raw_len < img_len) return stbi__err("not enough pixels","Corrupt PNG"); + if (raw_len < img_len) + return stbi__err("not enough pixels", "Corrupt PNG"); // Allocate two scan lines worth of filter workspace buffer. - filter_buf = (stbi_uc *) stbi__malloc_mad2(img_width_bytes, 2, 0); - if (!filter_buf) return stbi__err("outofmem", "Out of memory"); + filter_buf = (stbi_uc *)stbi__malloc_mad2(img_width_bytes, 2, 0); + if (!filter_buf) + return stbi__err("outofmem", "Out of memory"); // Filtering for low-bit-depth images - if (depth < 8) { + if (depth < 8) + { filter_bytes = 1; width = img_width_bytes; } - for (j=0; j < y; ++j) { + for (j = 0; j < y; ++j) + { // cur/prior filter buffers alternate - stbi_uc *cur = filter_buf + (j & 1)*img_width_bytes; - stbi_uc *prior = filter_buf + (~j & 1)*img_width_bytes; - stbi_uc *dest = a->out + stride*j; + stbi_uc *cur = filter_buf + (j & 1) * img_width_bytes; + stbi_uc *prior = filter_buf + (~j & 1) * img_width_bytes; + stbi_uc *dest = a->out + stride * j; int nk = width * filter_bytes; int filter = *raw++; // check filter type - if (filter > 4) { - all_ok = stbi__err("invalid filter","Corrupt PNG"); + if (filter > 4) + { + all_ok = stbi__err("invalid filter", "Corrupt PNG"); break; } // if first row, use special filter that doesn't sample previous row - if (j == 0) filter = first_row_filter[filter]; + if (j == 0) + filter = first_row_filter[filter]; // perform actual filtering - switch (filter) { + switch (filter) + { case STBI__F_none: memcpy(cur, raw, nk); break; case STBI__F_sub: memcpy(cur, raw, filter_bytes); for (k = filter_bytes; k < nk; ++k) - cur[k] = STBI__BYTECAST(raw[k] + cur[k-filter_bytes]); + cur[k] = STBI__BYTECAST(raw[k] + cur[k - filter_bytes]); break; case STBI__F_up: for (k = 0; k < nk; ++k) @@ -4767,50 +5466,62 @@ static int stbi__create_png_image_raw(stbi__png *a, stbi_uc *raw, stbi__uint32 r break; case STBI__F_avg: for (k = 0; k < filter_bytes; ++k) - cur[k] = STBI__BYTECAST(raw[k] + (prior[k]>>1)); + cur[k] = STBI__BYTECAST(raw[k] + (prior[k] >> 1)); for (k = filter_bytes; k < nk; ++k) - cur[k] = STBI__BYTECAST(raw[k] + ((prior[k] + cur[k-filter_bytes])>>1)); + cur[k] = STBI__BYTECAST(raw[k] + ((prior[k] + cur[k - filter_bytes]) >> 1)); break; case STBI__F_paeth: for (k = 0; k < filter_bytes; ++k) cur[k] = STBI__BYTECAST(raw[k] + prior[k]); // prior[k] == stbi__paeth(0,prior[k],0) for (k = filter_bytes; k < nk; ++k) - cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k-filter_bytes], prior[k], prior[k-filter_bytes])); + cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k - filter_bytes], prior[k], prior[k - filter_bytes])); break; case STBI__F_avg_first: memcpy(cur, raw, filter_bytes); for (k = filter_bytes; k < nk; ++k) - cur[k] = STBI__BYTECAST(raw[k] + (cur[k-filter_bytes] >> 1)); + cur[k] = STBI__BYTECAST(raw[k] + (cur[k - filter_bytes] >> 1)); break; } raw += nk; // expand decoded bits in cur to dest, also adding an extra alpha channel if desired - if (depth < 8) { + if (depth < 8) + { stbi_uc scale = (color == 0) ? stbi__depth_scale_table[depth] : 1; // scale grayscale values to 0..255 range stbi_uc *in = cur; stbi_uc *out = dest; stbi_uc inb = 0; - stbi__uint32 nsmp = x*img_n; + stbi__uint32 nsmp = x * img_n; // expand bits to bytes first - if (depth == 4) { - for (i=0; i < nsmp; ++i) { - if ((i & 1) == 0) inb = *in++; + if (depth == 4) + { + for (i = 0; i < nsmp; ++i) + { + if ((i & 1) == 0) + inb = *in++; *out++ = scale * (inb >> 4); inb <<= 4; } - } else if (depth == 2) { - for (i=0; i < nsmp; ++i) { - if ((i & 3) == 0) inb = *in++; + } + else if (depth == 2) + { + for (i = 0; i < nsmp; ++i) + { + if ((i & 3) == 0) + inb = *in++; *out++ = scale * (inb >> 6); inb <<= 2; } - } else { + } + else + { STBI_ASSERT(depth == 1); - for (i=0; i < nsmp; ++i) { - if ((i & 7) == 0) inb = *in++; + for (i = 0; i < nsmp; ++i) + { + if ((i & 7) == 0) + inb = *in++; *out++ = scale * (inb >> 7); inb <<= 1; } @@ -4819,29 +5530,41 @@ static int stbi__create_png_image_raw(stbi__png *a, stbi_uc *raw, stbi__uint32 r // insert alpha=255 values if desired if (img_n != out_n) stbi__create_png_alpha_expand8(dest, dest, x, img_n); - } else if (depth == 8) { + } + else if (depth == 8) + { if (img_n == out_n) - memcpy(dest, cur, x*img_n); + memcpy(dest, cur, x * img_n); else stbi__create_png_alpha_expand8(dest, cur, x, img_n); - } else if (depth == 16) { + } + else if (depth == 16) + { // convert the image data from big-endian to platform-native - stbi__uint16 *dest16 = (stbi__uint16*)dest; - stbi__uint32 nsmp = x*img_n; + stbi__uint16 *dest16 = (stbi__uint16 *)dest; + stbi__uint32 nsmp = x * img_n; - if (img_n == out_n) { + if (img_n == out_n) + { for (i = 0; i < nsmp; ++i, ++dest16, cur += 2) *dest16 = (cur[0] << 8) | cur[1]; - } else { - STBI_ASSERT(img_n+1 == out_n); - if (img_n == 1) { - for (i = 0; i < x; ++i, dest16 += 2, cur += 2) { + } + else + { + STBI_ASSERT(img_n + 1 == out_n); + if (img_n == 1) + { + for (i = 0; i < x; ++i, dest16 += 2, cur += 2) + { dest16[0] = (cur[0] << 8) | cur[1]; dest16[1] = 0xffff; } - } else { + } + else + { STBI_ASSERT(img_n == 3); - for (i = 0; i < x; ++i, dest16 += 4, cur += 6) { + for (i = 0; i < x; ++i, dest16 += 4, cur += 6) + { dest16[0] = (cur[0] << 8) | cur[1]; dest16[1] = (cur[2] << 8) | cur[3]; dest16[2] = (cur[4] << 8) | cur[5]; @@ -4853,7 +5576,8 @@ static int stbi__create_png_image_raw(stbi__png *a, stbi_uc *raw, stbi__uint32 r } STBI_FREE(filter_buf); - if (!all_ok) return 0; + if (!all_ok) + return 0; return 1; } @@ -4868,29 +5592,35 @@ static int stbi__create_png_image(stbi__png *a, stbi_uc *image_data, stbi__uint3 return stbi__create_png_image_raw(a, image_data, image_data_len, out_n, a->s->img_x, a->s->img_y, depth, color); // de-interlacing - final = (stbi_uc *) stbi__malloc_mad3(a->s->img_x, a->s->img_y, out_bytes, 0); - if (!final) return stbi__err("outofmem", "Out of memory"); - for (p=0; p < 7; ++p) { - int xorig[] = { 0,4,0,2,0,1,0 }; - int yorig[] = { 0,0,4,0,2,0,1 }; - int xspc[] = { 8,8,4,4,2,2,1 }; - int yspc[] = { 8,8,8,4,4,2,2 }; - int i,j,x,y; + final = (stbi_uc *)stbi__malloc_mad3(a->s->img_x, a->s->img_y, out_bytes, 0); + if (!final) + return stbi__err("outofmem", "Out of memory"); + for (p = 0; p < 7; ++p) + { + int xorig[] = {0, 4, 0, 2, 0, 1, 0}; + int yorig[] = {0, 0, 4, 0, 2, 0, 1}; + int xspc[] = {8, 8, 4, 4, 2, 2, 1}; + int yspc[] = {8, 8, 8, 4, 4, 2, 2}; + int i, j, x, y; // pass1_x[4] = 0, pass1_x[5] = 1, pass1_x[12] = 1 - x = (a->s->img_x - xorig[p] + xspc[p]-1) / xspc[p]; - y = (a->s->img_y - yorig[p] + yspc[p]-1) / yspc[p]; - if (x && y) { + x = (a->s->img_x - xorig[p] + xspc[p] - 1) / xspc[p]; + y = (a->s->img_y - yorig[p] + yspc[p] - 1) / yspc[p]; + if (x && y) + { stbi__uint32 img_len = ((((a->s->img_n * x * depth) + 7) >> 3) + 1) * y; - if (!stbi__create_png_image_raw(a, image_data, image_data_len, out_n, x, y, depth, color)) { + if (!stbi__create_png_image_raw(a, image_data, image_data_len, out_n, x, y, depth, color)) + { STBI_FREE(final); return 0; } - for (j=0; j < y; ++j) { - for (i=0; i < x; ++i) { - int out_y = j*yspc[p]+yorig[p]; - int out_x = i*xspc[p]+xorig[p]; - memcpy(final + out_y*a->s->img_x*out_bytes + out_x*out_bytes, - a->out + (j*x+i)*out_bytes, out_bytes); + for (j = 0; j < y; ++j) + { + for (i = 0; i < x; ++i) + { + int out_y = j * yspc[p] + yorig[p]; + int out_x = i * xspc[p] + xorig[p]; + memcpy(final + out_y * a->s->img_x * out_bytes + out_x * out_bytes, + a->out + (j * x + i) * out_bytes, out_bytes); } } STBI_FREE(a->out); @@ -4913,13 +5643,18 @@ static int stbi__compute_transparency(stbi__png *z, stbi_uc tc[3], int out_n) // already got 255 as the alpha value in the output STBI_ASSERT(out_n == 2 || out_n == 4); - if (out_n == 2) { - for (i=0; i < pixel_count; ++i) { + if (out_n == 2) + { + for (i = 0; i < pixel_count; ++i) + { p[1] = (p[0] == tc[0] ? 0 : 255); p += 2; } - } else { - for (i=0; i < pixel_count; ++i) { + } + else + { + for (i = 0; i < pixel_count; ++i) + { if (p[0] == tc[0] && p[1] == tc[1] && p[2] == tc[2]) p[3] = 0; p += 4; @@ -4932,19 +5667,24 @@ static int stbi__compute_transparency16(stbi__png *z, stbi__uint16 tc[3], int ou { stbi__context *s = z->s; stbi__uint32 i, pixel_count = s->img_x * s->img_y; - stbi__uint16 *p = (stbi__uint16*) z->out; + stbi__uint16 *p = (stbi__uint16 *)z->out; // compute color-based transparency, assuming we've // already got 65535 as the alpha value in the output STBI_ASSERT(out_n == 2 || out_n == 4); - if (out_n == 2) { - for (i = 0; i < pixel_count; ++i) { + if (out_n == 2) + { + for (i = 0; i < pixel_count; ++i) + { p[1] = (p[0] == tc[0] ? 0 : 65535); p += 2; } - } else { - for (i = 0; i < pixel_count; ++i) { + } + else + { + for (i = 0; i < pixel_count; ++i) + { if (p[0] == tc[0] && p[1] == tc[1] && p[2] == tc[2]) p[3] = 0; p += 4; @@ -4958,27 +5698,33 @@ static int stbi__expand_png_palette(stbi__png *a, stbi_uc *palette, int len, int stbi__uint32 i, pixel_count = a->s->img_x * a->s->img_y; stbi_uc *p, *temp_out, *orig = a->out; - p = (stbi_uc *) stbi__malloc_mad2(pixel_count, pal_img_n, 0); - if (p == NULL) return stbi__err("outofmem", "Out of memory"); + p = (stbi_uc *)stbi__malloc_mad2(pixel_count, pal_img_n, 0); + if (p == NULL) + return stbi__err("outofmem", "Out of memory"); // between here and free(out) below, exitting would leak temp_out = p; - if (pal_img_n == 3) { - for (i=0; i < pixel_count; ++i) { - int n = orig[i]*4; - p[0] = palette[n ]; - p[1] = palette[n+1]; - p[2] = palette[n+2]; + if (pal_img_n == 3) + { + for (i = 0; i < pixel_count; ++i) + { + int n = orig[i] * 4; + p[0] = palette[n]; + p[1] = palette[n + 1]; + p[2] = palette[n + 2]; p += 3; } - } else { - for (i=0; i < pixel_count; ++i) { - int n = orig[i]*4; - p[0] = palette[n ]; - p[1] = palette[n+1]; - p[2] = palette[n+2]; - p[3] = palette[n+3]; + } + else + { + for (i = 0; i < pixel_count; ++i) + { + int n = orig[i] * 4; + p[0] = palette[n]; + p[1] = palette[n + 1]; + p[2] = palette[n + 2]; + p[3] = palette[n + 3]; p += 4; } } @@ -5004,8 +5750,8 @@ STBIDEF void stbi_convert_iphone_png_to_rgb(int flag_true_if_should_convert) } #ifndef STBI_THREAD_LOCAL -#define stbi__unpremultiply_on_load stbi__unpremultiply_on_load_global -#define stbi__de_iphone_flag stbi__de_iphone_flag_global +#define stbi__unpremultiply_on_load stbi__unpremultiply_on_load_global +#define stbi__de_iphone_flag stbi__de_iphone_flag_global #else static STBI_THREAD_LOCAL int stbi__unpremultiply_on_load_local, stbi__unpremultiply_on_load_set; static STBI_THREAD_LOCAL int stbi__de_iphone_flag_local, stbi__de_iphone_flag_set; @@ -5022,12 +5768,12 @@ STBIDEF void stbi_convert_iphone_png_to_rgb_thread(int flag_true_if_should_conve stbi__de_iphone_flag_set = 1; } -#define stbi__unpremultiply_on_load (stbi__unpremultiply_on_load_set \ - ? stbi__unpremultiply_on_load_local \ - : stbi__unpremultiply_on_load_global) -#define stbi__de_iphone_flag (stbi__de_iphone_flag_set \ - ? stbi__de_iphone_flag_local \ - : stbi__de_iphone_flag_global) +#define stbi__unpremultiply_on_load (stbi__unpremultiply_on_load_set \ + ? stbi__unpremultiply_on_load_local \ + : stbi__unpremultiply_on_load_global) +#define stbi__de_iphone_flag (stbi__de_iphone_flag_set \ + ? stbi__de_iphone_flag_local \ + : stbi__de_iphone_flag_global) #endif // STBI_THREAD_LOCAL static void stbi__de_iphone(stbi__png *z) @@ -5036,34 +5782,46 @@ static void stbi__de_iphone(stbi__png *z) stbi__uint32 i, pixel_count = s->img_x * s->img_y; stbi_uc *p = z->out; - if (s->img_out_n == 3) { // convert bgr to rgb - for (i=0; i < pixel_count; ++i) { + if (s->img_out_n == 3) + { // convert bgr to rgb + for (i = 0; i < pixel_count; ++i) + { stbi_uc t = p[0]; p[0] = p[2]; p[2] = t; p += 3; } - } else { + } + else + { STBI_ASSERT(s->img_out_n == 4); - if (stbi__unpremultiply_on_load) { + if (stbi__unpremultiply_on_load) + { // convert bgr to rgb and unpremultiply - for (i=0; i < pixel_count; ++i) { + for (i = 0; i < pixel_count; ++i) + { stbi_uc a = p[3]; stbi_uc t = p[0]; - if (a) { + if (a) + { stbi_uc half = a / 2; p[0] = (p[2] * 255 + half) / a; p[1] = (p[1] * 255 + half) / a; - p[2] = ( t * 255 + half) / a; - } else { + p[2] = (t * 255 + half) / a; + } + else + { p[0] = p[2]; p[2] = t; } p += 4; } - } else { + } + else + { // convert bgr to rgb - for (i=0; i < pixel_count; ++i) { + for (i = 0; i < pixel_count; ++i) + { stbi_uc t = p[0]; p[0] = p[2]; p[2] = t; @@ -5073,187 +5831,273 @@ static void stbi__de_iphone(stbi__png *z) } } -#define STBI__PNG_TYPE(a,b,c,d) (((unsigned) (a) << 24) + ((unsigned) (b) << 16) + ((unsigned) (c) << 8) + (unsigned) (d)) +#define STBI__PNG_TYPE(a, b, c, d) (((unsigned)(a) << 24) + ((unsigned)(b) << 16) + ((unsigned)(c) << 8) + (unsigned)(d)) static int stbi__parse_png_file(stbi__png *z, int scan, int req_comp) { - stbi_uc palette[1024], pal_img_n=0; - stbi_uc has_trans=0, tc[3]={0}; + stbi_uc palette[1024], pal_img_n = 0; + stbi_uc has_trans = 0, tc[3] = {0}; stbi__uint16 tc16[3]; - stbi__uint32 ioff=0, idata_limit=0, i, pal_len=0; - int first=1,k,interlace=0, color=0, is_iphone=0; + stbi__uint32 ioff = 0, idata_limit = 0, i, pal_len = 0; + int first = 1, k, interlace = 0, color = 0, is_iphone = 0; stbi__context *s = z->s; z->expanded = NULL; z->idata = NULL; z->out = NULL; - if (!stbi__check_png_header(s)) return 0; + if (!stbi__check_png_header(s)) + return 0; - if (scan == STBI__SCAN_type) return 1; + if (scan == STBI__SCAN_type) + return 1; - for (;;) { + for (;;) + { stbi__pngchunk c = stbi__get_chunk_header(s); - switch (c.type) { - case STBI__PNG_TYPE('C','g','B','I'): - is_iphone = 1; - stbi__skip(s, c.length); - break; - case STBI__PNG_TYPE('I','H','D','R'): { - int comp,filter; - if (!first) return stbi__err("multiple IHDR","Corrupt PNG"); - first = 0; - if (c.length != 13) return stbi__err("bad IHDR len","Corrupt PNG"); - s->img_x = stbi__get32be(s); - s->img_y = stbi__get32be(s); - if (s->img_y > STBI_MAX_DIMENSIONS) return stbi__err("too large","Very large image (corrupt?)"); - if (s->img_x > STBI_MAX_DIMENSIONS) return stbi__err("too large","Very large image (corrupt?)"); - z->depth = stbi__get8(s); if (z->depth != 1 && z->depth != 2 && z->depth != 4 && z->depth != 8 && z->depth != 16) return stbi__err("1/2/4/8/16-bit only","PNG not supported: 1/2/4/8/16-bit only"); - color = stbi__get8(s); if (color > 6) return stbi__err("bad ctype","Corrupt PNG"); - if (color == 3 && z->depth == 16) return stbi__err("bad ctype","Corrupt PNG"); - if (color == 3) pal_img_n = 3; else if (color & 1) return stbi__err("bad ctype","Corrupt PNG"); - comp = stbi__get8(s); if (comp) return stbi__err("bad comp method","Corrupt PNG"); - filter= stbi__get8(s); if (filter) return stbi__err("bad filter method","Corrupt PNG"); - interlace = stbi__get8(s); if (interlace>1) return stbi__err("bad interlace method","Corrupt PNG"); - if (!s->img_x || !s->img_y) return stbi__err("0-pixel image","Corrupt PNG"); - if (!pal_img_n) { - s->img_n = (color & 2 ? 3 : 1) + (color & 4 ? 1 : 0); - if ((1 << 30) / s->img_x / s->img_n < s->img_y) return stbi__err("too large", "Image too large to decode"); - } else { - // if paletted, then pal_n is our final components, and - // img_n is # components to decompress/filter. - s->img_n = 1; - if ((1 << 30) / s->img_x / 4 < s->img_y) return stbi__err("too large","Corrupt PNG"); - } - // even with SCAN_header, have to scan to see if we have a tRNS - break; + switch (c.type) + { + case STBI__PNG_TYPE('C', 'g', 'B', 'I'): + is_iphone = 1; + stbi__skip(s, c.length); + break; + case STBI__PNG_TYPE('I', 'H', 'D', 'R'): + { + int comp, filter; + if (!first) + return stbi__err("multiple IHDR", "Corrupt PNG"); + first = 0; + if (c.length != 13) + return stbi__err("bad IHDR len", "Corrupt PNG"); + s->img_x = stbi__get32be(s); + s->img_y = stbi__get32be(s); + if (s->img_y > STBI_MAX_DIMENSIONS) + return stbi__err("too large", "Very large image (corrupt?)"); + if (s->img_x > STBI_MAX_DIMENSIONS) + return stbi__err("too large", "Very large image (corrupt?)"); + z->depth = stbi__get8(s); + if (z->depth != 1 && z->depth != 2 && z->depth != 4 && z->depth != 8 && z->depth != 16) + return stbi__err("1/2/4/8/16-bit only", "PNG not supported: 1/2/4/8/16-bit only"); + color = stbi__get8(s); + if (color > 6) + return stbi__err("bad ctype", "Corrupt PNG"); + if (color == 3 && z->depth == 16) + return stbi__err("bad ctype", "Corrupt PNG"); + if (color == 3) + pal_img_n = 3; + else if (color & 1) + return stbi__err("bad ctype", "Corrupt PNG"); + comp = stbi__get8(s); + if (comp) + return stbi__err("bad comp method", "Corrupt PNG"); + filter = stbi__get8(s); + if (filter) + return stbi__err("bad filter method", "Corrupt PNG"); + interlace = stbi__get8(s); + if (interlace > 1) + return stbi__err("bad interlace method", "Corrupt PNG"); + if (!s->img_x || !s->img_y) + return stbi__err("0-pixel image", "Corrupt PNG"); + if (!pal_img_n) + { + s->img_n = (color & 2 ? 3 : 1) + (color & 4 ? 1 : 0); + if ((1 << 30) / s->img_x / s->img_n < s->img_y) + return stbi__err("too large", "Image too large to decode"); } - - case STBI__PNG_TYPE('P','L','T','E'): { - if (first) return stbi__err("first not IHDR", "Corrupt PNG"); - if (c.length > 256*3) return stbi__err("invalid PLTE","Corrupt PNG"); - pal_len = c.length / 3; - if (pal_len * 3 != c.length) return stbi__err("invalid PLTE","Corrupt PNG"); - for (i=0; i < pal_len; ++i) { - palette[i*4+0] = stbi__get8(s); - palette[i*4+1] = stbi__get8(s); - palette[i*4+2] = stbi__get8(s); - palette[i*4+3] = 255; - } - break; + else + { + // if paletted, then pal_n is our final components, and + // img_n is # components to decompress/filter. + s->img_n = 1; + if ((1 << 30) / s->img_x / 4 < s->img_y) + return stbi__err("too large", "Corrupt PNG"); } + // even with SCAN_header, have to scan to see if we have a tRNS + break; + } - case STBI__PNG_TYPE('t','R','N','S'): { - if (first) return stbi__err("first not IHDR", "Corrupt PNG"); - if (z->idata) return stbi__err("tRNS after IDAT","Corrupt PNG"); - if (pal_img_n) { - if (scan == STBI__SCAN_header) { s->img_n = 4; return 1; } - if (pal_len == 0) return stbi__err("tRNS before PLTE","Corrupt PNG"); - if (c.length > pal_len) return stbi__err("bad tRNS len","Corrupt PNG"); - pal_img_n = 4; - for (i=0; i < c.length; ++i) - palette[i*4+3] = stbi__get8(s); - } else { - if (!(s->img_n & 1)) return stbi__err("tRNS with alpha","Corrupt PNG"); - if (c.length != (stbi__uint32) s->img_n*2) return stbi__err("bad tRNS len","Corrupt PNG"); - has_trans = 1; - // non-paletted with tRNS = constant alpha. if header-scanning, we can stop now. - if (scan == STBI__SCAN_header) { ++s->img_n; return 1; } - if (z->depth == 16) { - for (k = 0; k < s->img_n && k < 3; ++k) // extra loop test to suppress false GCC warning - tc16[k] = (stbi__uint16)stbi__get16be(s); // copy the values as-is - } else { - for (k = 0; k < s->img_n && k < 3; ++k) - tc[k] = (stbi_uc)(stbi__get16be(s) & 255) * stbi__depth_scale_table[z->depth]; // non 8-bit images will be larger - } - } - break; + case STBI__PNG_TYPE('P', 'L', 'T', 'E'): + { + if (first) + return stbi__err("first not IHDR", "Corrupt PNG"); + if (c.length > 256 * 3) + return stbi__err("invalid PLTE", "Corrupt PNG"); + pal_len = c.length / 3; + if (pal_len * 3 != c.length) + return stbi__err("invalid PLTE", "Corrupt PNG"); + for (i = 0; i < pal_len; ++i) + { + palette[i * 4 + 0] = stbi__get8(s); + palette[i * 4 + 1] = stbi__get8(s); + palette[i * 4 + 2] = stbi__get8(s); + palette[i * 4 + 3] = 255; } + break; + } - case STBI__PNG_TYPE('I','D','A','T'): { - if (first) return stbi__err("first not IHDR", "Corrupt PNG"); - if (pal_img_n && !pal_len) return stbi__err("no PLTE","Corrupt PNG"); - if (scan == STBI__SCAN_header) { - // header scan definitely stops at first IDAT - if (pal_img_n) - s->img_n = pal_img_n; + case STBI__PNG_TYPE('t', 'R', 'N', 'S'): + { + if (first) + return stbi__err("first not IHDR", "Corrupt PNG"); + if (z->idata) + return stbi__err("tRNS after IDAT", "Corrupt PNG"); + if (pal_img_n) + { + if (scan == STBI__SCAN_header) + { + s->img_n = 4; return 1; } - if (c.length > (1u << 30)) return stbi__err("IDAT size limit", "IDAT section larger than 2^30 bytes"); - if ((int)(ioff + c.length) < (int)ioff) return 0; - if (ioff + c.length > idata_limit) { - stbi__uint32 idata_limit_old = idata_limit; - stbi_uc *p; - if (idata_limit == 0) idata_limit = c.length > 4096 ? c.length : 4096; - while (ioff + c.length > idata_limit) - idata_limit *= 2; - STBI_NOTUSED(idata_limit_old); - p = (stbi_uc *) STBI_REALLOC_SIZED(z->idata, idata_limit_old, idata_limit); if (p == NULL) return stbi__err("outofmem", "Out of memory"); - z->idata = p; - } - if (!stbi__getn(s, z->idata+ioff,c.length)) return stbi__err("outofdata","Corrupt PNG"); - ioff += c.length; - break; + if (pal_len == 0) + return stbi__err("tRNS before PLTE", "Corrupt PNG"); + if (c.length > pal_len) + return stbi__err("bad tRNS len", "Corrupt PNG"); + pal_img_n = 4; + for (i = 0; i < c.length; ++i) + palette[i * 4 + 3] = stbi__get8(s); } - - case STBI__PNG_TYPE('I','E','N','D'): { - stbi__uint32 raw_len, bpl; - if (first) return stbi__err("first not IHDR", "Corrupt PNG"); - if (scan != STBI__SCAN_load) return 1; - if (z->idata == NULL) return stbi__err("no IDAT","Corrupt PNG"); - // initial guess for decoded data size to avoid unnecessary reallocs - bpl = (s->img_x * z->depth + 7) / 8; // bytes per line, per component - raw_len = bpl * s->img_y * s->img_n /* pixels */ + s->img_y /* filter mode per row */; - z->expanded = (stbi_uc *) stbi_zlib_decode_malloc_guesssize_headerflag((char *) z->idata, ioff, raw_len, (int *) &raw_len, !is_iphone); - if (z->expanded == NULL) return 0; // zlib should set error - STBI_FREE(z->idata); z->idata = NULL; - if ((req_comp == s->img_n+1 && req_comp != 3 && !pal_img_n) || has_trans) - s->img_out_n = s->img_n+1; - else - s->img_out_n = s->img_n; - if (!stbi__create_png_image(z, z->expanded, raw_len, s->img_out_n, z->depth, color, interlace)) return 0; - if (has_trans) { - if (z->depth == 16) { - if (!stbi__compute_transparency16(z, tc16, s->img_out_n)) return 0; - } else { - if (!stbi__compute_transparency(z, tc, s->img_out_n)) return 0; - } - } - if (is_iphone && stbi__de_iphone_flag && s->img_out_n > 2) - stbi__de_iphone(z); - if (pal_img_n) { - // pal_img_n == 3 or 4 - s->img_n = pal_img_n; // record the actual colors we had - s->img_out_n = pal_img_n; - if (req_comp >= 3) s->img_out_n = req_comp; - if (!stbi__expand_png_palette(z, palette, pal_len, s->img_out_n)) - return 0; - } else if (has_trans) { - // non-paletted image with tRNS -> source image has (constant) alpha + else + { + if (!(s->img_n & 1)) + return stbi__err("tRNS with alpha", "Corrupt PNG"); + if (c.length != (stbi__uint32)s->img_n * 2) + return stbi__err("bad tRNS len", "Corrupt PNG"); + has_trans = 1; + // non-paletted with tRNS = constant alpha. if header-scanning, we can stop now. + if (scan == STBI__SCAN_header) + { ++s->img_n; + return 1; } - STBI_FREE(z->expanded); z->expanded = NULL; - // end of PNG chunk, read and skip CRC - stbi__get32be(s); + if (z->depth == 16) + { + for (k = 0; k < s->img_n && k < 3; ++k) // extra loop test to suppress false GCC warning + tc16[k] = (stbi__uint16)stbi__get16be(s); // copy the values as-is + } + else + { + for (k = 0; k < s->img_n && k < 3; ++k) + tc[k] = (stbi_uc)(stbi__get16be(s) & 255) * stbi__depth_scale_table[z->depth]; // non 8-bit images will be larger + } + } + break; + } + + case STBI__PNG_TYPE('I', 'D', 'A', 'T'): + { + if (first) + return stbi__err("first not IHDR", "Corrupt PNG"); + if (pal_img_n && !pal_len) + return stbi__err("no PLTE", "Corrupt PNG"); + if (scan == STBI__SCAN_header) + { + // header scan definitely stops at first IDAT + if (pal_img_n) + s->img_n = pal_img_n; return 1; } + if (c.length > (1u << 30)) + return stbi__err("IDAT size limit", "IDAT section larger than 2^30 bytes"); + if ((int)(ioff + c.length) < (int)ioff) + return 0; + if (ioff + c.length > idata_limit) + { + stbi__uint32 idata_limit_old = idata_limit; + stbi_uc *p; + if (idata_limit == 0) + idata_limit = c.length > 4096 ? c.length : 4096; + while (ioff + c.length > idata_limit) + idata_limit *= 2; + STBI_NOTUSED(idata_limit_old); + p = (stbi_uc *)STBI_REALLOC_SIZED(z->idata, idata_limit_old, idata_limit); + if (p == NULL) + return stbi__err("outofmem", "Out of memory"); + z->idata = p; + } + if (!stbi__getn(s, z->idata + ioff, c.length)) + return stbi__err("outofdata", "Corrupt PNG"); + ioff += c.length; + break; + } - default: - // if critical, fail - if (first) return stbi__err("first not IHDR", "Corrupt PNG"); - if ((c.type & (1 << 29)) == 0) { - #ifndef STBI_NO_FAILURE_STRINGS - // not threadsafe - static char invalid_chunk[] = "XXXX PNG chunk not known"; - invalid_chunk[0] = STBI__BYTECAST(c.type >> 24); - invalid_chunk[1] = STBI__BYTECAST(c.type >> 16); - invalid_chunk[2] = STBI__BYTECAST(c.type >> 8); - invalid_chunk[3] = STBI__BYTECAST(c.type >> 0); - #endif - return stbi__err(invalid_chunk, "PNG not supported: unknown PNG chunk type"); + case STBI__PNG_TYPE('I', 'E', 'N', 'D'): + { + stbi__uint32 raw_len, bpl; + if (first) + return stbi__err("first not IHDR", "Corrupt PNG"); + if (scan != STBI__SCAN_load) + return 1; + if (z->idata == NULL) + return stbi__err("no IDAT", "Corrupt PNG"); + // initial guess for decoded data size to avoid unnecessary reallocs + bpl = (s->img_x * z->depth + 7) / 8; // bytes per line, per component + raw_len = bpl * s->img_y * s->img_n /* pixels */ + s->img_y /* filter mode per row */; + z->expanded = (stbi_uc *)stbi_zlib_decode_malloc_guesssize_headerflag((char *)z->idata, ioff, raw_len, (int *)&raw_len, !is_iphone); + if (z->expanded == NULL) + return 0; // zlib should set error + STBI_FREE(z->idata); + z->idata = NULL; + if ((req_comp == s->img_n + 1 && req_comp != 3 && !pal_img_n) || has_trans) + s->img_out_n = s->img_n + 1; + else + s->img_out_n = s->img_n; + if (!stbi__create_png_image(z, z->expanded, raw_len, s->img_out_n, z->depth, color, interlace)) + return 0; + if (has_trans) + { + if (z->depth == 16) + { + if (!stbi__compute_transparency16(z, tc16, s->img_out_n)) + return 0; } - stbi__skip(s, c.length); - break; + else + { + if (!stbi__compute_transparency(z, tc, s->img_out_n)) + return 0; + } + } + if (is_iphone && stbi__de_iphone_flag && s->img_out_n > 2) + stbi__de_iphone(z); + if (pal_img_n) + { + // pal_img_n == 3 or 4 + s->img_n = pal_img_n; // record the actual colors we had + s->img_out_n = pal_img_n; + if (req_comp >= 3) + s->img_out_n = req_comp; + if (!stbi__expand_png_palette(z, palette, pal_len, s->img_out_n)) + return 0; + } + else if (has_trans) + { + // non-paletted image with tRNS -> source image has (constant) alpha + ++s->img_n; + } + STBI_FREE(z->expanded); + z->expanded = NULL; + // end of PNG chunk, read and skip CRC + stbi__get32be(s); + return 1; + } + + default: + // if critical, fail + if (first) + return stbi__err("first not IHDR", "Corrupt PNG"); + if ((c.type & (1 << 29)) == 0) + { +#ifndef STBI_NO_FAILURE_STRINGS + // not threadsafe + static char invalid_chunk[] = "XXXX PNG chunk not known"; + invalid_chunk[0] = STBI__BYTECAST(c.type >> 24); + invalid_chunk[1] = STBI__BYTECAST(c.type >> 16); + invalid_chunk[2] = STBI__BYTECAST(c.type >> 8); + invalid_chunk[3] = STBI__BYTECAST(c.type >> 0); +#endif + return stbi__err(invalid_chunk, "PNG not supported: unknown PNG chunk type"); + } + stbi__skip(s, c.length); + break; } // end of PNG chunk, read and skip CRC stbi__get32be(s); @@ -5262,9 +6106,11 @@ static int stbi__parse_png_file(stbi__png *z, int scan, int req_comp) static void *stbi__do_png(stbi__png *p, int *x, int *y, int *n, int req_comp, stbi__result_info *ri) { - void *result=NULL; - if (req_comp < 0 || req_comp > 4) return stbi__errpuc("bad req_comp", "Internal error"); - if (stbi__parse_png_file(p, STBI__SCAN_load, req_comp)) { + void *result = NULL; + if (req_comp < 0 || req_comp > 4) + return stbi__errpuc("bad req_comp", "Internal error"); + if (stbi__parse_png_file(p, STBI__SCAN_load, req_comp)) + { if (p->depth <= 8) ri->bits_per_channel = 8; else if (p->depth == 16) @@ -5273,21 +6119,27 @@ static void *stbi__do_png(stbi__png *p, int *x, int *y, int *n, int req_comp, st return stbi__errpuc("bad bits_per_channel", "PNG not supported: unsupported color depth"); result = p->out; p->out = NULL; - if (req_comp && req_comp != p->s->img_out_n) { + if (req_comp && req_comp != p->s->img_out_n) + { if (ri->bits_per_channel == 8) - result = stbi__convert_format((unsigned char *) result, p->s->img_out_n, req_comp, p->s->img_x, p->s->img_y); + result = stbi__convert_format((unsigned char *)result, p->s->img_out_n, req_comp, p->s->img_x, p->s->img_y); else - result = stbi__convert_format16((stbi__uint16 *) result, p->s->img_out_n, req_comp, p->s->img_x, p->s->img_y); + result = stbi__convert_format16((stbi__uint16 *)result, p->s->img_out_n, req_comp, p->s->img_x, p->s->img_y); p->s->img_out_n = req_comp; - if (result == NULL) return result; + if (result == NULL) + return result; } *x = p->s->img_x; *y = p->s->img_y; - if (n) *n = p->s->img_n; + if (n) + *n = p->s->img_n; } - STBI_FREE(p->out); p->out = NULL; - STBI_FREE(p->expanded); p->expanded = NULL; - STBI_FREE(p->idata); p->idata = NULL; + STBI_FREE(p->out); + p->out = NULL; + STBI_FREE(p->expanded); + p->expanded = NULL; + STBI_FREE(p->idata); + p->idata = NULL; return result; } @@ -5296,7 +6148,7 @@ static void *stbi__png_load(stbi__context *s, int *x, int *y, int *comp, int req { stbi__png p; p.s = s; - return stbi__do_png(&p, x,y,comp,req_comp, ri); + return stbi__do_png(&p, x, y, comp, req_comp, ri); } static int stbi__png_test(stbi__context *s) @@ -5309,13 +6161,17 @@ static int stbi__png_test(stbi__context *s) static int stbi__png_info_raw(stbi__png *p, int *x, int *y, int *comp) { - if (!stbi__parse_png_file(p, STBI__SCAN_header, 0)) { - stbi__rewind( p->s ); + if (!stbi__parse_png_file(p, STBI__SCAN_header, 0)) + { + stbi__rewind(p->s); return 0; } - if (x) *x = p->s->img_x; - if (y) *y = p->s->img_y; - if (comp) *comp = p->s->img_n; + if (x) + *x = p->s->img_x; + if (y) + *y = p->s->img_y; + if (comp) + *comp = p->s->img_n; return 1; } @@ -5331,8 +6187,9 @@ static int stbi__png_is16(stbi__context *s) stbi__png p; p.s = s; if (!stbi__png_info_raw(&p, NULL, NULL, NULL)) - return 0; - if (p.depth != 16) { + return 0; + if (p.depth != 16) + { stbi__rewind(p.s); return 0; } @@ -5347,8 +6204,10 @@ static int stbi__bmp_test_raw(stbi__context *s) { int r; int sz; - if (stbi__get8(s) != 'B') return 0; - if (stbi__get8(s) != 'M') return 0; + if (stbi__get8(s) != 'B') + return 0; + if (stbi__get8(s) != 'M') + return 0; stbi__get32le(s); // discard filesize stbi__get16le(s); // discard reserved stbi__get16le(s); // discard reserved @@ -5365,27 +6224,46 @@ static int stbi__bmp_test(stbi__context *s) return r; } - // returns 0..31 for the highest set bit static int stbi__high_bit(unsigned int z) { - int n=0; - if (z == 0) return -1; - if (z >= 0x10000) { n += 16; z >>= 16; } - if (z >= 0x00100) { n += 8; z >>= 8; } - if (z >= 0x00010) { n += 4; z >>= 4; } - if (z >= 0x00004) { n += 2; z >>= 2; } - if (z >= 0x00002) { n += 1;/* >>= 1;*/ } + int n = 0; + if (z == 0) + return -1; + if (z >= 0x10000) + { + n += 16; + z >>= 16; + } + if (z >= 0x00100) + { + n += 8; + z >>= 8; + } + if (z >= 0x00010) + { + n += 4; + z >>= 4; + } + if (z >= 0x00004) + { + n += 2; + z >>= 2; + } + if (z >= 0x00002) + { + n += 1; /* >>= 1;*/ + } return n; } static int stbi__bitcount(unsigned int a) { - a = (a & 0x55555555) + ((a >> 1) & 0x55555555); // max 2 - a = (a & 0x33333333) + ((a >> 2) & 0x33333333); // max 4 - a = (a + (a >> 4)) & 0x0f0f0f0f; // max 8 per 4, now 8 bits - a = (a + (a >> 8)); // max 16 per 8 bits - a = (a + (a >> 16)); // max 32 per 8 bits + a = (a & 0x55555555) + ((a >> 1) & 0x55555555); // max 2 + a = (a & 0x33333333) + ((a >> 2) & 0x33333333); // max 4 + a = (a + (a >> 4)) & 0x0f0f0f0f; // max 8 per 4, now 8 bits + a = (a + (a >> 8)); // max 16 per 8 bits + a = (a + (a >> 16)); // max 32 per 8 bits return a & 0xff; } @@ -5395,27 +6273,41 @@ static int stbi__bitcount(unsigned int a) static int stbi__shiftsigned(unsigned int v, int shift, int bits) { static unsigned int mul_table[9] = { - 0, - 0xff/*0b11111111*/, 0x55/*0b01010101*/, 0x49/*0b01001001*/, 0x11/*0b00010001*/, - 0x21/*0b00100001*/, 0x41/*0b01000001*/, 0x81/*0b10000001*/, 0x01/*0b00000001*/, + 0, + 0xff /*0b11111111*/, + 0x55 /*0b01010101*/, + 0x49 /*0b01001001*/, + 0x11 /*0b00010001*/, + 0x21 /*0b00100001*/, + 0x41 /*0b01000001*/, + 0x81 /*0b10000001*/, + 0x01 /*0b00000001*/, }; static unsigned int shift_table[9] = { - 0, 0,0,1,0,2,4,6,0, + 0, + 0, + 0, + 1, + 0, + 2, + 4, + 6, + 0, }; if (shift < 0) v <<= -shift; else v >>= shift; STBI_ASSERT(v < 256); - v >>= (8-bits); + v >>= (8 - bits); STBI_ASSERT(bits >= 0 && bits <= 8); - return (int) ((unsigned) v * mul_table[bits]) >> shift_table[bits]; + return (int)((unsigned)v * mul_table[bits]) >> shift_table[bits]; } typedef struct { int bpp, offset, hsz; - unsigned int mr,mg,mb,ma, all_a; + unsigned int mr, mg, mb, ma, all_a; int extra_read; } stbi__bmp_data; @@ -5425,18 +6317,24 @@ static int stbi__bmp_set_mask_defaults(stbi__bmp_data *info, int compress) if (compress == 3) return 1; - if (compress == 0) { - if (info->bpp == 16) { + if (compress == 0) + { + if (info->bpp == 16) + { info->mr = 31u << 10; - info->mg = 31u << 5; - info->mb = 31u << 0; - } else if (info->bpp == 32) { + info->mg = 31u << 5; + info->mb = 31u << 0; + } + else if (info->bpp == 32) + { info->mr = 0xffu << 16; - info->mg = 0xffu << 8; - info->mb = 0xffu << 0; + info->mg = 0xffu << 8; + info->mb = 0xffu << 0; info->ma = 0xffu << 24; info->all_a = 0; // if all_a is 0 at end, then we loaded alpha channel but it was all 0 - } else { + } + else + { // otherwise, use defaults, which is all-0 info->mr = info->mg = info->mb = info->ma = 0; } @@ -5448,7 +6346,8 @@ static int stbi__bmp_set_mask_defaults(stbi__bmp_data *info, int compress) static void *stbi__bmp_parse_header(stbi__context *s, stbi__bmp_data *info) { int hsz; - if (stbi__get8(s) != 'B' || stbi__get8(s) != 'M') return stbi__errpuc("not BMP", "Corrupt BMP"); + if (stbi__get8(s) != 'B' || stbi__get8(s) != 'M') + return stbi__errpuc("not BMP", "Corrupt BMP"); stbi__get32le(s); // discard filesize stbi__get16le(s); // discard reserved stbi__get16le(s); // discard reserved @@ -5457,52 +6356,72 @@ static void *stbi__bmp_parse_header(stbi__context *s, stbi__bmp_data *info) info->mr = info->mg = info->mb = info->ma = 0; info->extra_read = 14; - if (info->offset < 0) return stbi__errpuc("bad BMP", "bad BMP"); + if (info->offset < 0) + return stbi__errpuc("bad BMP", "bad BMP"); - if (hsz != 12 && hsz != 40 && hsz != 56 && hsz != 108 && hsz != 124) return stbi__errpuc("unknown BMP", "BMP type not supported: unknown"); - if (hsz == 12) { + if (hsz != 12 && hsz != 40 && hsz != 56 && hsz != 108 && hsz != 124) + return stbi__errpuc("unknown BMP", "BMP type not supported: unknown"); + if (hsz == 12) + { s->img_x = stbi__get16le(s); s->img_y = stbi__get16le(s); - } else { + } + else + { s->img_x = stbi__get32le(s); s->img_y = stbi__get32le(s); } - if (stbi__get16le(s) != 1) return stbi__errpuc("bad BMP", "bad BMP"); + if (stbi__get16le(s) != 1) + return stbi__errpuc("bad BMP", "bad BMP"); info->bpp = stbi__get16le(s); - if (hsz != 12) { + if (hsz != 12) + { int compress = stbi__get32le(s); - if (compress == 1 || compress == 2) return stbi__errpuc("BMP RLE", "BMP type not supported: RLE"); - if (compress >= 4) return stbi__errpuc("BMP JPEG/PNG", "BMP type not supported: unsupported compression"); // this includes PNG/JPEG modes - if (compress == 3 && info->bpp != 16 && info->bpp != 32) return stbi__errpuc("bad BMP", "bad BMP"); // bitfields requires 16 or 32 bits/pixel - stbi__get32le(s); // discard sizeof - stbi__get32le(s); // discard hres - stbi__get32le(s); // discard vres - stbi__get32le(s); // discard colorsused - stbi__get32le(s); // discard max important - if (hsz == 40 || hsz == 56) { - if (hsz == 56) { + if (compress == 1 || compress == 2) + return stbi__errpuc("BMP RLE", "BMP type not supported: RLE"); + if (compress >= 4) + return stbi__errpuc("BMP JPEG/PNG", "BMP type not supported: unsupported compression"); // this includes PNG/JPEG modes + if (compress == 3 && info->bpp != 16 && info->bpp != 32) + return stbi__errpuc("bad BMP", "bad BMP"); // bitfields requires 16 or 32 bits/pixel + stbi__get32le(s); // discard sizeof + stbi__get32le(s); // discard hres + stbi__get32le(s); // discard vres + stbi__get32le(s); // discard colorsused + stbi__get32le(s); // discard max important + if (hsz == 40 || hsz == 56) + { + if (hsz == 56) + { stbi__get32le(s); stbi__get32le(s); stbi__get32le(s); stbi__get32le(s); } - if (info->bpp == 16 || info->bpp == 32) { - if (compress == 0) { + if (info->bpp == 16 || info->bpp == 32) + { + if (compress == 0) + { stbi__bmp_set_mask_defaults(info, compress); - } else if (compress == 3) { + } + else if (compress == 3) + { info->mr = stbi__get32le(s); info->mg = stbi__get32le(s); info->mb = stbi__get32le(s); info->extra_read += 12; // not documented, but generated by photoshop and handled by mspaint - if (info->mr == info->mg && info->mg == info->mb) { + if (info->mr == info->mg && info->mg == info->mb) + { // ?!?!? return stbi__errpuc("bad BMP", "bad BMP"); } - } else + } + else return stbi__errpuc("bad BMP", "bad BMP"); } - } else { + } + else + { // V4/V5 header int i; if (hsz != 108 && hsz != 124) @@ -5514,9 +6433,10 @@ static void *stbi__bmp_parse_header(stbi__context *s, stbi__bmp_data *info) if (compress != 3) // override mr/mg/mb unless in BI_BITFIELDS mode, as per docs stbi__bmp_set_mask_defaults(info, compress); stbi__get32le(s); // discard color space - for (i=0; i < 12; ++i) + for (i = 0; i < 12; ++i) stbi__get32le(s); // discard color space parameters - if (hsz == 124) { + if (hsz == 124) + { stbi__get32le(s); // discard rendering intent stbi__get32le(s); // discard offset of profile data stbi__get32le(s); // discard size of profile data @@ -5524,16 +6444,15 @@ static void *stbi__bmp_parse_header(stbi__context *s, stbi__bmp_data *info) } } } - return (void *) 1; + return (void *)1; } - static void *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri) { stbi_uc *out; - unsigned int mr=0,mg=0,mb=0,ma=0, all_a; + unsigned int mr = 0, mg = 0, mb = 0, ma = 0, all_a; stbi_uc pal[256][4]; - int psize=0,i,j,width; + int psize = 0, i, j, width; int flip_vertically, pad, target; stbi__bmp_data info; STBI_NOTUSED(ri); @@ -5542,11 +6461,13 @@ static void *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int req if (stbi__bmp_parse_header(s, &info) == NULL) return NULL; // error code already set - flip_vertically = ((int) s->img_y) > 0; - s->img_y = abs((int) s->img_y); + flip_vertically = ((int)s->img_y) > 0; + s->img_y = abs((int)s->img_y); - if (s->img_y > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large","Very large image (corrupt?)"); - if (s->img_x > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large","Very large image (corrupt?)"); + if (s->img_y > STBI_MAX_DIMENSIONS) + return stbi__errpuc("too large", "Very large image (corrupt?)"); + if (s->img_x > STBI_MAX_DIMENSIONS) + return stbi__errpuc("too large", "Very large image (corrupt?)"); mr = info.mr; mg = info.mg; @@ -5554,29 +6475,37 @@ static void *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int req ma = info.ma; all_a = info.all_a; - if (info.hsz == 12) { + if (info.hsz == 12) + { if (info.bpp < 24) psize = (info.offset - info.extra_read - 24) / 3; - } else { + } + else + { if (info.bpp < 16) psize = (info.offset - info.extra_read - info.hsz) >> 2; } - if (psize == 0) { + if (psize == 0) + { // accept some number of extra bytes after the header, but if the offset points either to before // the header ends or implies a large amount of extra data, reject the file as malformed int bytes_read_so_far = s->callback_already_read + (int)(s->img_buffer - s->img_buffer_original); - int header_limit = 1024; // max we actually read is below 256 bytes currently. - int extra_data_limit = 256*4; // what ordinarily goes here is a palette; 256 entries*4 bytes is its max size. - if (bytes_read_so_far <= 0 || bytes_read_so_far > header_limit) { + int header_limit = 1024; // max we actually read is below 256 bytes currently. + int extra_data_limit = 256 * 4; // what ordinarily goes here is a palette; 256 entries*4 bytes is its max size. + if (bytes_read_so_far <= 0 || bytes_read_so_far > header_limit) + { return stbi__errpuc("bad header", "Corrupt BMP"); } // we established that bytes_read_so_far is positive and sensible. // the first half of this test rejects offsets that are either too small positives, or // negative, and guarantees that info.offset >= bytes_read_so_far > 0. this in turn // ensures the number computed in the second half of the test can't overflow. - if (info.offset < bytes_read_so_far || info.offset - bytes_read_so_far > extra_data_limit) { + if (info.offset < bytes_read_so_far || info.offset - bytes_read_so_far > extra_data_limit) + { return stbi__errpuc("bad offset", "Corrupt BMP"); - } else { + } + else + { stbi__skip(s, info.offset - bytes_read_so_far); } } @@ -5594,110 +6523,168 @@ static void *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int req if (!stbi__mad3sizes_valid(target, s->img_x, s->img_y, 0)) return stbi__errpuc("too large", "Corrupt BMP"); - out = (stbi_uc *) stbi__malloc_mad3(target, s->img_x, s->img_y, 0); - if (!out) return stbi__errpuc("outofmem", "Out of memory"); - if (info.bpp < 16) { - int z=0; - if (psize == 0 || psize > 256) { STBI_FREE(out); return stbi__errpuc("invalid", "Corrupt BMP"); } - for (i=0; i < psize; ++i) { + out = (stbi_uc *)stbi__malloc_mad3(target, s->img_x, s->img_y, 0); + if (!out) + return stbi__errpuc("outofmem", "Out of memory"); + if (info.bpp < 16) + { + int z = 0; + if (psize == 0 || psize > 256) + { + STBI_FREE(out); + return stbi__errpuc("invalid", "Corrupt BMP"); + } + for (i = 0; i < psize; ++i) + { pal[i][2] = stbi__get8(s); pal[i][1] = stbi__get8(s); pal[i][0] = stbi__get8(s); - if (info.hsz != 12) stbi__get8(s); + if (info.hsz != 12) + stbi__get8(s); pal[i][3] = 255; } stbi__skip(s, info.offset - info.extra_read - info.hsz - psize * (info.hsz == 12 ? 3 : 4)); - if (info.bpp == 1) width = (s->img_x + 7) >> 3; - else if (info.bpp == 4) width = (s->img_x + 1) >> 1; - else if (info.bpp == 8) width = s->img_x; - else { STBI_FREE(out); return stbi__errpuc("bad bpp", "Corrupt BMP"); } - pad = (-width)&3; - if (info.bpp == 1) { - for (j=0; j < (int) s->img_y; ++j) { + if (info.bpp == 1) + width = (s->img_x + 7) >> 3; + else if (info.bpp == 4) + width = (s->img_x + 1) >> 1; + else if (info.bpp == 8) + width = s->img_x; + else + { + STBI_FREE(out); + return stbi__errpuc("bad bpp", "Corrupt BMP"); + } + pad = (-width) & 3; + if (info.bpp == 1) + { + for (j = 0; j < (int)s->img_y; ++j) + { int bit_offset = 7, v = stbi__get8(s); - for (i=0; i < (int) s->img_x; ++i) { - int color = (v>>bit_offset)&0x1; + for (i = 0; i < (int)s->img_x; ++i) + { + int color = (v >> bit_offset) & 0x1; out[z++] = pal[color][0]; out[z++] = pal[color][1]; out[z++] = pal[color][2]; - if (target == 4) out[z++] = 255; - if (i+1 == (int) s->img_x) break; - if((--bit_offset) < 0) { + if (target == 4) + out[z++] = 255; + if (i + 1 == (int)s->img_x) + break; + if ((--bit_offset) < 0) + { bit_offset = 7; v = stbi__get8(s); } } stbi__skip(s, pad); } - } else { - for (j=0; j < (int) s->img_y; ++j) { - for (i=0; i < (int) s->img_x; i += 2) { - int v=stbi__get8(s),v2=0; - if (info.bpp == 4) { + } + else + { + for (j = 0; j < (int)s->img_y; ++j) + { + for (i = 0; i < (int)s->img_x; i += 2) + { + int v = stbi__get8(s), v2 = 0; + if (info.bpp == 4) + { v2 = v & 15; v >>= 4; } out[z++] = pal[v][0]; out[z++] = pal[v][1]; out[z++] = pal[v][2]; - if (target == 4) out[z++] = 255; - if (i+1 == (int) s->img_x) break; + if (target == 4) + out[z++] = 255; + if (i + 1 == (int)s->img_x) + break; v = (info.bpp == 8) ? stbi__get8(s) : v2; out[z++] = pal[v][0]; out[z++] = pal[v][1]; out[z++] = pal[v][2]; - if (target == 4) out[z++] = 255; + if (target == 4) + out[z++] = 255; } stbi__skip(s, pad); } } - } else { - int rshift=0,gshift=0,bshift=0,ashift=0,rcount=0,gcount=0,bcount=0,acount=0; + } + else + { + int rshift = 0, gshift = 0, bshift = 0, ashift = 0, rcount = 0, gcount = 0, bcount = 0, acount = 0; int z = 0; - int easy=0; + int easy = 0; stbi__skip(s, info.offset - info.extra_read - info.hsz); - if (info.bpp == 24) width = 3 * s->img_x; - else if (info.bpp == 16) width = 2*s->img_x; - else /* bpp = 32 and pad = 0 */ width=0; + if (info.bpp == 24) + width = 3 * s->img_x; + else if (info.bpp == 16) + width = 2 * s->img_x; + else /* bpp = 32 and pad = 0 */ + width = 0; pad = (-width) & 3; - if (info.bpp == 24) { + if (info.bpp == 24) + { easy = 1; - } else if (info.bpp == 32) { + } + else if (info.bpp == 32) + { if (mb == 0xff && mg == 0xff00 && mr == 0x00ff0000 && ma == 0xff000000) easy = 2; } - if (!easy) { - if (!mr || !mg || !mb) { STBI_FREE(out); return stbi__errpuc("bad masks", "Corrupt BMP"); } + if (!easy) + { + if (!mr || !mg || !mb) + { + STBI_FREE(out); + return stbi__errpuc("bad masks", "Corrupt BMP"); + } // right shift amt to put high bit in position #7 - rshift = stbi__high_bit(mr)-7; rcount = stbi__bitcount(mr); - gshift = stbi__high_bit(mg)-7; gcount = stbi__bitcount(mg); - bshift = stbi__high_bit(mb)-7; bcount = stbi__bitcount(mb); - ashift = stbi__high_bit(ma)-7; acount = stbi__bitcount(ma); - if (rcount > 8 || gcount > 8 || bcount > 8 || acount > 8) { STBI_FREE(out); return stbi__errpuc("bad masks", "Corrupt BMP"); } + rshift = stbi__high_bit(mr) - 7; + rcount = stbi__bitcount(mr); + gshift = stbi__high_bit(mg) - 7; + gcount = stbi__bitcount(mg); + bshift = stbi__high_bit(mb) - 7; + bcount = stbi__bitcount(mb); + ashift = stbi__high_bit(ma) - 7; + acount = stbi__bitcount(ma); + if (rcount > 8 || gcount > 8 || bcount > 8 || acount > 8) + { + STBI_FREE(out); + return stbi__errpuc("bad masks", "Corrupt BMP"); + } } - for (j=0; j < (int) s->img_y; ++j) { - if (easy) { - for (i=0; i < (int) s->img_x; ++i) { + for (j = 0; j < (int)s->img_y; ++j) + { + if (easy) + { + for (i = 0; i < (int)s->img_x; ++i) + { unsigned char a; - out[z+2] = stbi__get8(s); - out[z+1] = stbi__get8(s); - out[z+0] = stbi__get8(s); + out[z + 2] = stbi__get8(s); + out[z + 1] = stbi__get8(s); + out[z + 0] = stbi__get8(s); z += 3; a = (easy == 2 ? stbi__get8(s) : 255); all_a |= a; - if (target == 4) out[z++] = a; + if (target == 4) + out[z++] = a; } - } else { + } + else + { int bpp = info.bpp; - for (i=0; i < (int) s->img_x; ++i) { - stbi__uint32 v = (bpp == 16 ? (stbi__uint32) stbi__get16le(s) : stbi__get32le(s)); + for (i = 0; i < (int)s->img_x; ++i) + { + stbi__uint32 v = (bpp == 16 ? (stbi__uint32)stbi__get16le(s) : stbi__get32le(s)); unsigned int a; out[z++] = STBI__BYTECAST(stbi__shiftsigned(v & mr, rshift, rcount)); out[z++] = STBI__BYTECAST(stbi__shiftsigned(v & mg, gshift, gcount)); out[z++] = STBI__BYTECAST(stbi__shiftsigned(v & mb, bshift, bcount)); a = (ma ? stbi__shiftsigned(v & ma, ashift, acount) : 255); all_a |= a; - if (target == 4) out[z++] = STBI__BYTECAST(a); + if (target == 4) + out[z++] = STBI__BYTECAST(a); } } stbi__skip(s, pad); @@ -5706,28 +6693,36 @@ static void *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int req // if alpha channel is all 0s, replace with all 255s if (target == 4 && all_a == 0) - for (i=4*s->img_x*s->img_y-1; i >= 0; i -= 4) + for (i = 4 * s->img_x * s->img_y - 1; i >= 0; i -= 4) out[i] = 255; - if (flip_vertically) { + if (flip_vertically) + { stbi_uc t; - for (j=0; j < (int) s->img_y>>1; ++j) { - stbi_uc *p1 = out + j *s->img_x*target; - stbi_uc *p2 = out + (s->img_y-1-j)*s->img_x*target; - for (i=0; i < (int) s->img_x*target; ++i) { - t = p1[i]; p1[i] = p2[i]; p2[i] = t; + for (j = 0; j < (int)s->img_y >> 1; ++j) + { + stbi_uc *p1 = out + j * s->img_x * target; + stbi_uc *p2 = out + (s->img_y - 1 - j) * s->img_x * target; + for (i = 0; i < (int)s->img_x * target; ++i) + { + t = p1[i]; + p1[i] = p2[i]; + p2[i] = t; } } } - if (req_comp && req_comp != target) { + if (req_comp && req_comp != target) + { out = stbi__convert_format(out, target, req_comp, s->img_x, s->img_y); - if (out == NULL) return out; // stbi__convert_format frees input on failure + if (out == NULL) + return out; // stbi__convert_format frees input on failure } *x = s->img_x; *y = s->img_y; - if (comp) *comp = s->img_n; + if (comp) + *comp = s->img_n; return out; } #endif @@ -5736,110 +6731,147 @@ static void *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int req // by Jonathan Dummer #ifndef STBI_NO_TGA // returns STBI_rgb or whatever, 0 on error -static int stbi__tga_get_comp(int bits_per_pixel, int is_grey, int* is_rgb16) +static int stbi__tga_get_comp(int bits_per_pixel, int is_grey, int *is_rgb16) { // only RGB or RGBA (incl. 16bit) or grey allowed - if (is_rgb16) *is_rgb16 = 0; - switch(bits_per_pixel) { - case 8: return STBI_grey; - case 16: if(is_grey) return STBI_grey_alpha; - // fallthrough - case 15: if(is_rgb16) *is_rgb16 = 1; - return STBI_rgb; - case 24: // fallthrough - case 32: return bits_per_pixel/8; - default: return 0; + if (is_rgb16) + *is_rgb16 = 0; + switch (bits_per_pixel) + { + case 8: + return STBI_grey; + case 16: + if (is_grey) + return STBI_grey_alpha; + // fallthrough + case 15: + if (is_rgb16) + *is_rgb16 = 1; + return STBI_rgb; + case 24: // fallthrough + case 32: + return bits_per_pixel / 8; + default: + return 0; } } static int stbi__tga_info(stbi__context *s, int *x, int *y, int *comp) { - int tga_w, tga_h, tga_comp, tga_image_type, tga_bits_per_pixel, tga_colormap_bpp; - int sz, tga_colormap_type; - stbi__get8(s); // discard Offset - tga_colormap_type = stbi__get8(s); // colormap type - if( tga_colormap_type > 1 ) { - stbi__rewind(s); - return 0; // only RGB or indexed allowed - } - tga_image_type = stbi__get8(s); // image type - if ( tga_colormap_type == 1 ) { // colormapped (paletted) image - if (tga_image_type != 1 && tga_image_type != 9) { - stbi__rewind(s); - return 0; - } - stbi__skip(s,4); // skip index of first colormap entry and number of entries - sz = stbi__get8(s); // check bits per palette color entry - if ( (sz != 8) && (sz != 15) && (sz != 16) && (sz != 24) && (sz != 32) ) { - stbi__rewind(s); - return 0; - } - stbi__skip(s,4); // skip image x and y origin - tga_colormap_bpp = sz; - } else { // "normal" image w/o colormap - only RGB or grey allowed, +/- RLE - if ( (tga_image_type != 2) && (tga_image_type != 3) && (tga_image_type != 10) && (tga_image_type != 11) ) { - stbi__rewind(s); - return 0; // only RGB or grey allowed, +/- RLE - } - stbi__skip(s,9); // skip colormap specification and image x/y origin - tga_colormap_bpp = 0; - } - tga_w = stbi__get16le(s); - if( tga_w < 1 ) { - stbi__rewind(s); - return 0; // test width - } - tga_h = stbi__get16le(s); - if( tga_h < 1 ) { - stbi__rewind(s); - return 0; // test height - } - tga_bits_per_pixel = stbi__get8(s); // bits per pixel - stbi__get8(s); // ignore alpha bits - if (tga_colormap_bpp != 0) { - if((tga_bits_per_pixel != 8) && (tga_bits_per_pixel != 16)) { - // when using a colormap, tga_bits_per_pixel is the size of the indexes - // I don't think anything but 8 or 16bit indexes makes sense - stbi__rewind(s); - return 0; - } - tga_comp = stbi__tga_get_comp(tga_colormap_bpp, 0, NULL); - } else { - tga_comp = stbi__tga_get_comp(tga_bits_per_pixel, (tga_image_type == 3) || (tga_image_type == 11), NULL); - } - if(!tga_comp) { + int tga_w, tga_h, tga_comp, tga_image_type, tga_bits_per_pixel, tga_colormap_bpp; + int sz, tga_colormap_type; + stbi__get8(s); // discard Offset + tga_colormap_type = stbi__get8(s); // colormap type + if (tga_colormap_type > 1) + { + stbi__rewind(s); + return 0; // only RGB or indexed allowed + } + tga_image_type = stbi__get8(s); // image type + if (tga_colormap_type == 1) + { // colormapped (paletted) image + if (tga_image_type != 1 && tga_image_type != 9) + { + stbi__rewind(s); + return 0; + } + stbi__skip(s, 4); // skip index of first colormap entry and number of entries + sz = stbi__get8(s); // check bits per palette color entry + if ((sz != 8) && (sz != 15) && (sz != 16) && (sz != 24) && (sz != 32)) + { + stbi__rewind(s); + return 0; + } + stbi__skip(s, 4); // skip image x and y origin + tga_colormap_bpp = sz; + } + else + { // "normal" image w/o colormap - only RGB or grey allowed, +/- RLE + if ((tga_image_type != 2) && (tga_image_type != 3) && (tga_image_type != 10) && (tga_image_type != 11)) + { + stbi__rewind(s); + return 0; // only RGB or grey allowed, +/- RLE + } + stbi__skip(s, 9); // skip colormap specification and image x/y origin + tga_colormap_bpp = 0; + } + tga_w = stbi__get16le(s); + if (tga_w < 1) + { + stbi__rewind(s); + return 0; // test width + } + tga_h = stbi__get16le(s); + if (tga_h < 1) + { + stbi__rewind(s); + return 0; // test height + } + tga_bits_per_pixel = stbi__get8(s); // bits per pixel + stbi__get8(s); // ignore alpha bits + if (tga_colormap_bpp != 0) + { + if ((tga_bits_per_pixel != 8) && (tga_bits_per_pixel != 16)) + { + // when using a colormap, tga_bits_per_pixel is the size of the indexes + // I don't think anything but 8 or 16bit indexes makes sense + stbi__rewind(s); + return 0; + } + tga_comp = stbi__tga_get_comp(tga_colormap_bpp, 0, NULL); + } + else + { + tga_comp = stbi__tga_get_comp(tga_bits_per_pixel, (tga_image_type == 3) || (tga_image_type == 11), NULL); + } + if (!tga_comp) + { stbi__rewind(s); return 0; - } - if (x) *x = tga_w; - if (y) *y = tga_h; - if (comp) *comp = tga_comp; - return 1; // seems to have passed everything + } + if (x) + *x = tga_w; + if (y) + *y = tga_h; + if (comp) + *comp = tga_comp; + return 1; // seems to have passed everything } static int stbi__tga_test(stbi__context *s) { int res = 0; int sz, tga_color_type; - stbi__get8(s); // discard Offset - tga_color_type = stbi__get8(s); // color type - if ( tga_color_type > 1 ) goto errorEnd; // only RGB or indexed allowed - sz = stbi__get8(s); // image type - if ( tga_color_type == 1 ) { // colormapped (paletted) image - if (sz != 1 && sz != 9) goto errorEnd; // colortype 1 demands image type 1 or 9 - stbi__skip(s,4); // skip index of first colormap entry and number of entries - sz = stbi__get8(s); // check bits per palette color entry - if ( (sz != 8) && (sz != 15) && (sz != 16) && (sz != 24) && (sz != 32) ) goto errorEnd; - stbi__skip(s,4); // skip image x and y origin - } else { // "normal" image w/o colormap - if ( (sz != 2) && (sz != 3) && (sz != 10) && (sz != 11) ) goto errorEnd; // only RGB or grey allowed, +/- RLE - stbi__skip(s,9); // skip colormap specification and image x/y origin + stbi__get8(s); // discard Offset + tga_color_type = stbi__get8(s); // color type + if (tga_color_type > 1) + goto errorEnd; // only RGB or indexed allowed + sz = stbi__get8(s); // image type + if (tga_color_type == 1) + { // colormapped (paletted) image + if (sz != 1 && sz != 9) + goto errorEnd; // colortype 1 demands image type 1 or 9 + stbi__skip(s, 4); // skip index of first colormap entry and number of entries + sz = stbi__get8(s); // check bits per palette color entry + if ((sz != 8) && (sz != 15) && (sz != 16) && (sz != 24) && (sz != 32)) + goto errorEnd; + stbi__skip(s, 4); // skip image x and y origin } - if ( stbi__get16le(s) < 1 ) goto errorEnd; // test width - if ( stbi__get16le(s) < 1 ) goto errorEnd; // test height - sz = stbi__get8(s); // bits per pixel - if ( (tga_color_type == 1) && (sz != 8) && (sz != 16) ) goto errorEnd; // for colormapped images, bpp is size of an index - if ( (sz != 8) && (sz != 15) && (sz != 16) && (sz != 24) && (sz != 32) ) goto errorEnd; + else + { // "normal" image w/o colormap + if ((sz != 2) && (sz != 3) && (sz != 10) && (sz != 11)) + goto errorEnd; // only RGB or grey allowed, +/- RLE + stbi__skip(s, 9); // skip colormap specification and image x/y origin + } + if (stbi__get16le(s) < 1) + goto errorEnd; // test width + if (stbi__get16le(s) < 1) + goto errorEnd; // test height + sz = stbi__get8(s); // bits per pixel + if ((tga_color_type == 1) && (sz != 8) && (sz != 16)) + goto errorEnd; // para colormapped images, bpp is size of an index + if ((sz != 8) && (sz != 15) && (sz != 16) && (sz != 24) && (sz != 32)) + goto errorEnd; res = 1; // if we got this far, everything's good and we can return 1 instead of 0 @@ -5849,7 +6881,7 @@ errorEnd: } // read 16bit value and convert to 24bit RGB -static void stbi__tga_read_rgb16(stbi__context *s, stbi_uc* out) +static void stbi__tga_read_rgb16(stbi__context *s, stbi_uc *out) { stbi__uint16 px = (stbi__uint16)stbi__get16le(s); stbi__uint16 fiveBitMask = 31; @@ -5858,9 +6890,9 @@ static void stbi__tga_read_rgb16(stbi__context *s, stbi_uc* out) int g = (px >> 5) & fiveBitMask; int b = px & fiveBitMask; // Note that this saves the data in RGB(A) order, so it doesn't need to be swapped later - out[0] = (stbi_uc)((r * 255)/31); - out[1] = (stbi_uc)((g * 255)/31); - out[2] = (stbi_uc)((b * 255)/31); + out[0] = (stbi_uc)((r * 255) / 31); + out[1] = (stbi_uc)((g * 255) / 31); + out[2] = (stbi_uc)((b * 255) / 31); // some people claim that the most significant bit might be used for alpha // (possibly if an alpha-bit is set in the "image descriptor byte") @@ -5883,7 +6915,7 @@ static void *stbi__tga_load(stbi__context *s, int *x, int *y, int *comp, int req int tga_width = stbi__get16le(s); int tga_height = stbi__get16le(s); int tga_bits_per_pixel = stbi__get8(s); - int tga_comp, tga_rgb16=0; + int tga_comp, tga_rgb16 = 0; int tga_inverted = stbi__get8(s); // int tga_alpha_bits = tga_inverted & 15; // the 4 lowest bits - unused (useless?) // image data @@ -5898,11 +6930,13 @@ static void *stbi__tga_load(stbi__context *s, int *x, int *y, int *comp, int req STBI_NOTUSED(tga_x_origin); // @TODO STBI_NOTUSED(tga_y_origin); // @TODO - if (tga_height > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large","Very large image (corrupt?)"); - if (tga_width > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large","Very large image (corrupt?)"); + if (tga_height > STBI_MAX_DIMENSIONS) + return stbi__errpuc("too large", "Very large image (corrupt?)"); + if (tga_width > STBI_MAX_DIMENSIONS) + return stbi__errpuc("too large", "Very large image (corrupt?)"); // do a tiny bit of precessing - if ( tga_image_type >= 8 ) + if (tga_image_type >= 8) { tga_image_type -= 8; tga_is_RLE = 1; @@ -5910,105 +6944,128 @@ static void *stbi__tga_load(stbi__context *s, int *x, int *y, int *comp, int req tga_inverted = 1 - ((tga_inverted >> 5) & 1); // If I'm paletted, then I'll use the number of bits from the palette - if ( tga_indexed ) tga_comp = stbi__tga_get_comp(tga_palette_bits, 0, &tga_rgb16); - else tga_comp = stbi__tga_get_comp(tga_bits_per_pixel, (tga_image_type == 3), &tga_rgb16); + if (tga_indexed) + tga_comp = stbi__tga_get_comp(tga_palette_bits, 0, &tga_rgb16); + else + tga_comp = stbi__tga_get_comp(tga_bits_per_pixel, (tga_image_type == 3), &tga_rgb16); - if(!tga_comp) // shouldn't really happen, stbi__tga_test() should have ensured basic consistency + if (!tga_comp) // shouldn't really happen, stbi__tga_test() should have ensured basic consistency return stbi__errpuc("bad format", "Can't find out TGA pixelformat"); // tga info *x = tga_width; *y = tga_height; - if (comp) *comp = tga_comp; + if (comp) + *comp = tga_comp; if (!stbi__mad3sizes_valid(tga_width, tga_height, tga_comp, 0)) return stbi__errpuc("too large", "Corrupt TGA"); - tga_data = (unsigned char*)stbi__malloc_mad3(tga_width, tga_height, tga_comp, 0); - if (!tga_data) return stbi__errpuc("outofmem", "Out of memory"); + tga_data = (unsigned char *)stbi__malloc_mad3(tga_width, tga_height, tga_comp, 0); + if (!tga_data) + return stbi__errpuc("outofmem", "Out of memory"); // skip to the data's starting position (offset usually = 0) - stbi__skip(s, tga_offset ); + stbi__skip(s, tga_offset); - if ( !tga_indexed && !tga_is_RLE && !tga_rgb16 ) { - for (i=0; i < tga_height; ++i) { - int row = tga_inverted ? tga_height -i - 1 : i; - stbi_uc *tga_row = tga_data + row*tga_width*tga_comp; + if (!tga_indexed && !tga_is_RLE && !tga_rgb16) + { + for (i = 0; i < tga_height; ++i) + { + int row = tga_inverted ? tga_height - i - 1 : i; + stbi_uc *tga_row = tga_data + row * tga_width * tga_comp; stbi__getn(s, tga_row, tga_width * tga_comp); } - } else { + } + else + { // do I need to load a palette? - if ( tga_indexed) + if (tga_indexed) { - if (tga_palette_len == 0) { /* you have to have at least one entry! */ + if (tga_palette_len == 0) + { /* you have to have at least one entry! */ STBI_FREE(tga_data); return stbi__errpuc("bad palette", "Corrupt TGA"); } // any data to skip? (offset usually = 0) - stbi__skip(s, tga_palette_start ); + stbi__skip(s, tga_palette_start); // load the palette - tga_palette = (unsigned char*)stbi__malloc_mad2(tga_palette_len, tga_comp, 0); - if (!tga_palette) { + tga_palette = (unsigned char *)stbi__malloc_mad2(tga_palette_len, tga_comp, 0); + if (!tga_palette) + { STBI_FREE(tga_data); return stbi__errpuc("outofmem", "Out of memory"); } - if (tga_rgb16) { + if (tga_rgb16) + { stbi_uc *pal_entry = tga_palette; STBI_ASSERT(tga_comp == STBI_rgb); - for (i=0; i < tga_palette_len; ++i) { + for (i = 0; i < tga_palette_len; ++i) + { stbi__tga_read_rgb16(s, pal_entry); pal_entry += tga_comp; } - } else if (!stbi__getn(s, tga_palette, tga_palette_len * tga_comp)) { - STBI_FREE(tga_data); - STBI_FREE(tga_palette); - return stbi__errpuc("bad palette", "Corrupt TGA"); + } + else if (!stbi__getn(s, tga_palette, tga_palette_len * tga_comp)) + { + STBI_FREE(tga_data); + STBI_FREE(tga_palette); + return stbi__errpuc("bad palette", "Corrupt TGA"); } } // load the data - for (i=0; i < tga_width * tga_height; ++i) + for (i = 0; i < tga_width * tga_height; ++i) { // if I'm in RLE mode, do I need to get a RLE stbi__pngchunk? - if ( tga_is_RLE ) + if (tga_is_RLE) { - if ( RLE_count == 0 ) + if (RLE_count == 0) { // yep, get the next byte as a RLE command int RLE_cmd = stbi__get8(s); RLE_count = 1 + (RLE_cmd & 127); RLE_repeating = RLE_cmd >> 7; read_next_pixel = 1; - } else if ( !RLE_repeating ) + } + else if (!RLE_repeating) { read_next_pixel = 1; } - } else + } + else { read_next_pixel = 1; } // OK, if I need to read a pixel, do it now - if ( read_next_pixel ) + if (read_next_pixel) { // load however much data we did have - if ( tga_indexed ) + if (tga_indexed) { // read in index, then perform the lookup int pal_idx = (tga_bits_per_pixel == 8) ? stbi__get8(s) : stbi__get16le(s); - if ( pal_idx >= tga_palette_len ) { + if (pal_idx >= tga_palette_len) + { // invalid index pal_idx = 0; } pal_idx *= tga_comp; - for (j = 0; j < tga_comp; ++j) { - raw_data[j] = tga_palette[pal_idx+j]; + for (j = 0; j < tga_comp; ++j) + { + raw_data[j] = tga_palette[pal_idx + j]; } - } else if(tga_rgb16) { + } + else if (tga_rgb16) + { STBI_ASSERT(tga_comp == STBI_rgb); stbi__tga_read_rgb16(s, raw_data); - } else { + } + else + { // read in the data raw - for (j = 0; j < tga_comp; ++j) { + for (j = 0; j < tga_comp; ++j) + { raw_data[j] = stbi__get8(s); } } @@ -6018,15 +7075,15 @@ static void *stbi__tga_load(stbi__context *s, int *x, int *y, int *comp, int req // copy data for (j = 0; j < tga_comp; ++j) - tga_data[i*tga_comp+j] = raw_data[j]; + tga_data[i * tga_comp + j] = raw_data[j]; // in case we're in RLE mode, keep counting down --RLE_count; } // do I need to invert the image? - if ( tga_inverted ) + if (tga_inverted) { - for (j = 0; j*2 < tga_height; ++j) + for (j = 0; j * 2 < tga_height; ++j) { int index1 = j * tga_width * tga_comp; int index2 = (tga_height - 1 - j) * tga_width * tga_comp; @@ -6041,17 +7098,17 @@ static void *stbi__tga_load(stbi__context *s, int *x, int *y, int *comp, int req } } // clear my palette, if I had one - if ( tga_palette != NULL ) + if (tga_palette != NULL) { - STBI_FREE( tga_palette ); + STBI_FREE(tga_palette); } } // swap RGB - if the source data was RGB16, it already is in the right order if (tga_comp >= 3 && !tga_rgb16) { - unsigned char* tga_pixel = tga_data; - for (i=0; i < tga_width * tga_height; ++i) + unsigned char *tga_pixel = tga_data; + for (i = 0; i < tga_width * tga_height; ++i) { unsigned char temp = tga_pixel[0]; tga_pixel[0] = tga_pixel[2]; @@ -6067,7 +7124,7 @@ static void *stbi__tga_load(stbi__context *s, int *x, int *y, int *comp, int req // the things I do to get rid of an error message, and yet keep // Microsoft's C compilers happy... [8^( tga_palette_start = tga_palette_len = tga_palette_bits = - tga_x_origin = tga_y_origin = 0; + tga_x_origin = tga_y_origin = 0; STBI_NOTUSED(tga_palette_start); // OK, done return tga_data; @@ -6090,29 +7147,39 @@ static int stbi__psd_decode_rle(stbi__context *s, stbi_uc *p, int pixelCount) int count, nleft, len; count = 0; - while ((nleft = pixelCount - count) > 0) { + while ((nleft = pixelCount - count) > 0) + { len = stbi__get8(s); - if (len == 128) { + if (len == 128) + { // No-op. - } else if (len < 128) { + } + else if (len < 128) + { // Copy next len+1 bytes literally. len++; - if (len > nleft) return 0; // corrupt data + if (len > nleft) + return 0; // corrupt data count += len; - while (len) { + while (len) + { *p = stbi__get8(s); p += 4; len--; } - } else if (len > 128) { - stbi_uc val; + } + else if (len > 128) + { + stbi_uc val; // Next -len+1 bytes in the dest are replicated from next source byte. // (Interpret len as a negative 8-bit int.) len = 257 - len; - if (len > nleft) return 0; // corrupt data + if (len > nleft) + return 0; // corrupt data val = stbi__get8(s); count += len; - while (len) { + while (len) + { *p = val; p += 4; len--; @@ -6129,12 +7196,12 @@ static void *stbi__psd_load(stbi__context *s, int *x, int *y, int *comp, int req int channelCount, compression; int channel, i; int bitdepth; - int w,h; + int w, h; stbi_uc *out; STBI_NOTUSED(ri); // Check identifier - if (stbi__get32be(s) != 0x38425053) // "8BPS" + if (stbi__get32be(s) != 0x38425053) // "8BPS" return stbi__errpuc("not PSD", "Corrupt PSD image"); // Check file type version. @@ -6142,7 +7209,7 @@ static void *stbi__psd_load(stbi__context *s, int *x, int *y, int *comp, int req return stbi__errpuc("wrong version", "Unsupported version of PSD image"); // Skip 6 reserved bytes. - stbi__skip(s, 6 ); + stbi__skip(s, 6); // Read the number of channels (R, G, B, A, etc). channelCount = stbi__get16be(s); @@ -6153,8 +7220,10 @@ static void *stbi__psd_load(stbi__context *s, int *x, int *y, int *comp, int req h = stbi__get32be(s); w = stbi__get32be(s); - if (h > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large","Very large image (corrupt?)"); - if (w > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large","Very large image (corrupt?)"); + if (h > STBI_MAX_DIMENSIONS) + return stbi__errpuc("too large", "Very large image (corrupt?)"); + if (w > STBI_MAX_DIMENSIONS) + return stbi__errpuc("too large", "Very large image (corrupt?)"); // Make sure the depth is 8 bits. bitdepth = stbi__get16be(s); @@ -6175,13 +7244,13 @@ static void *stbi__psd_load(stbi__context *s, int *x, int *y, int *comp, int req return stbi__errpuc("wrong color format", "PSD is not in RGB color format"); // Skip the Mode Data. (It's the palette for indexed color; other info for other modes.) - stbi__skip(s,stbi__get32be(s) ); + stbi__skip(s, stbi__get32be(s)); // Skip the image resources. (resolution, pen tool paths, etc) - stbi__skip(s, stbi__get32be(s) ); + stbi__skip(s, stbi__get32be(s)); // Skip the reserved data. - stbi__skip(s, stbi__get32be(s) ); + stbi__skip(s, stbi__get32be(s)); // Find out if the data is compressed. // Known values: @@ -6197,20 +7266,24 @@ static void *stbi__psd_load(stbi__context *s, int *x, int *y, int *comp, int req // Create the destination image. - if (!compression && bitdepth == 16 && bpc == 16) { - out = (stbi_uc *) stbi__malloc_mad3(8, w, h, 0); + if (!compression && bitdepth == 16 && bpc == 16) + { + out = (stbi_uc *)stbi__malloc_mad3(8, w, h, 0); ri->bits_per_channel = 16; - } else - out = (stbi_uc *) stbi__malloc(4 * w*h); + } + else + out = (stbi_uc *)stbi__malloc(4 * w * h); - if (!out) return stbi__errpuc("outofmem", "Out of memory"); - pixelCount = w*h; + if (!out) + return stbi__errpuc("outofmem", "Out of memory"); + pixelCount = w * h; // Initialize the data to zero. - //memset( out, 0, pixelCount * 4 ); + // memset( out, 0, pixelCount * 4 ); // Finally, the image data. - if (compression) { + if (compression) + { // RLE as used by .PSD and .TIFF // Loop until you get the number of unpacked bytes you are expecting: // Read the next source byte into n. @@ -6221,56 +7294,75 @@ static void *stbi__psd_load(stbi__context *s, int *x, int *y, int *comp, int req // The RLE-compressed data is preceded by a 2-byte data count for each row in the data, // which we're going to just skip. - stbi__skip(s, h * channelCount * 2 ); + stbi__skip(s, h * channelCount * 2); // Read the RLE data by channel. - for (channel = 0; channel < 4; channel++) { + for (channel = 0; channel < 4; channel++) + { stbi_uc *p; - p = out+channel; - if (channel >= channelCount) { + p = out + channel; + if (channel >= channelCount) + { // Fill this channel with default data. for (i = 0; i < pixelCount; i++, p += 4) *p = (channel == 3 ? 255 : 0); - } else { + } + else + { // Read the RLE data. - if (!stbi__psd_decode_rle(s, p, pixelCount)) { + if (!stbi__psd_decode_rle(s, p, pixelCount)) + { STBI_FREE(out); return stbi__errpuc("corrupt", "bad RLE data"); } } } - - } else { + } + else + { // We're at the raw image data. It's each channel in order (Red, Green, Blue, Alpha, ...) // where each channel consists of an 8-bit (or 16-bit) value for each pixel in the image. // Read the data by channel. - for (channel = 0; channel < 4; channel++) { - if (channel >= channelCount) { + for (channel = 0; channel < 4; channel++) + { + if (channel >= channelCount) + { // Fill this channel with default data. - if (bitdepth == 16 && bpc == 16) { - stbi__uint16 *q = ((stbi__uint16 *) out) + channel; + if (bitdepth == 16 && bpc == 16) + { + stbi__uint16 *q = ((stbi__uint16 *)out) + channel; stbi__uint16 val = channel == 3 ? 65535 : 0; for (i = 0; i < pixelCount; i++, q += 4) *q = val; - } else { - stbi_uc *p = out+channel; + } + else + { + stbi_uc *p = out + channel; stbi_uc val = channel == 3 ? 255 : 0; for (i = 0; i < pixelCount; i++, p += 4) *p = val; } - } else { - if (ri->bits_per_channel == 16) { // output bpc - stbi__uint16 *q = ((stbi__uint16 *) out) + channel; + } + else + { + if (ri->bits_per_channel == 16) + { // output bpc + stbi__uint16 *q = ((stbi__uint16 *)out) + channel; for (i = 0; i < pixelCount; i++, q += 4) - *q = (stbi__uint16) stbi__get16be(s); - } else { - stbi_uc *p = out+channel; - if (bitdepth == 16) { // input bpc + *q = (stbi__uint16)stbi__get16be(s); + } + else + { + stbi_uc *p = out + channel; + if (bitdepth == 16) + { // input bpc for (i = 0; i < pixelCount; i++, p += 4) - *p = (stbi_uc) (stbi__get16be(s) >> 8); - } else { + *p = (stbi_uc)(stbi__get16be(s) >> 8); + } + else + { for (i = 0; i < pixelCount; i++, p += 4) *p = stbi__get8(s); } @@ -6280,44 +7372,55 @@ static void *stbi__psd_load(stbi__context *s, int *x, int *y, int *comp, int req } // remove weird white matte from PSD - if (channelCount >= 4) { - if (ri->bits_per_channel == 16) { - for (i=0; i < w*h; ++i) { - stbi__uint16 *pixel = (stbi__uint16 *) out + 4*i; - if (pixel[3] != 0 && pixel[3] != 65535) { + if (channelCount >= 4) + { + if (ri->bits_per_channel == 16) + { + for (i = 0; i < w * h; ++i) + { + stbi__uint16 *pixel = (stbi__uint16 *)out + 4 * i; + if (pixel[3] != 0 && pixel[3] != 65535) + { float a = pixel[3] / 65535.0f; float ra = 1.0f / a; float inv_a = 65535.0f * (1 - ra); - pixel[0] = (stbi__uint16) (pixel[0]*ra + inv_a); - pixel[1] = (stbi__uint16) (pixel[1]*ra + inv_a); - pixel[2] = (stbi__uint16) (pixel[2]*ra + inv_a); + pixel[0] = (stbi__uint16)(pixel[0] * ra + inv_a); + pixel[1] = (stbi__uint16)(pixel[1] * ra + inv_a); + pixel[2] = (stbi__uint16)(pixel[2] * ra + inv_a); } } - } else { - for (i=0; i < w*h; ++i) { - unsigned char *pixel = out + 4*i; - if (pixel[3] != 0 && pixel[3] != 255) { + } + else + { + for (i = 0; i < w * h; ++i) + { + unsigned char *pixel = out + 4 * i; + if (pixel[3] != 0 && pixel[3] != 255) + { float a = pixel[3] / 255.0f; float ra = 1.0f / a; float inv_a = 255.0f * (1 - ra); - pixel[0] = (unsigned char) (pixel[0]*ra + inv_a); - pixel[1] = (unsigned char) (pixel[1]*ra + inv_a); - pixel[2] = (unsigned char) (pixel[2]*ra + inv_a); + pixel[0] = (unsigned char)(pixel[0] * ra + inv_a); + pixel[1] = (unsigned char)(pixel[1] * ra + inv_a); + pixel[2] = (unsigned char)(pixel[2] * ra + inv_a); } } } } // convert to desired output format - if (req_comp && req_comp != 4) { + if (req_comp && req_comp != 4) + { if (ri->bits_per_channel == 16) - out = (stbi_uc *) stbi__convert_format16((stbi__uint16 *) out, 4, req_comp, w, h); + out = (stbi_uc *)stbi__convert_format16((stbi__uint16 *)out, 4, req_comp, w, h); else out = stbi__convert_format(out, 4, req_comp, w, h); - if (out == NULL) return out; // stbi__convert_format frees input on failure + if (out == NULL) + return out; // stbi__convert_format frees input on failure } - if (comp) *comp = 4; + if (comp) + *comp = 4; *y = h; *x = w; @@ -6333,10 +7436,10 @@ static void *stbi__psd_load(stbi__context *s, int *x, int *y, int *comp, int req // See http://ozviz.wasp.uwa.edu.au/~pbourke/dataformats/softimagepic/ #ifndef STBI_NO_PIC -static int stbi__pic_is4(stbi__context *s,const char *str) +static int stbi__pic_is4(stbi__context *s, const char *str) { int i; - for (i=0; i<4; ++i) + for (i = 0; i < 4; ++i) if (stbi__get8(s) != (stbi_uc)str[i]) return 0; @@ -6347,13 +7450,13 @@ static int stbi__pic_test_core(stbi__context *s) { int i; - if (!stbi__pic_is4(s,"\x53\x80\xF6\x34")) + if (!stbi__pic_is4(s, "\x53\x80\xF6\x34")) return 0; - for(i=0;i<84;++i) + for (i = 0; i < 84; ++i) stbi__get8(s); - if (!stbi__pic_is4(s,"PICT")) + if (!stbi__pic_is4(s, "PICT")) return 0; return 1; @@ -6361,135 +7464,155 @@ static int stbi__pic_test_core(stbi__context *s) typedef struct { - stbi_uc size,type,channel; + stbi_uc size, type, channel; } stbi__pic_packet; static stbi_uc *stbi__readval(stbi__context *s, int channel, stbi_uc *dest) { - int mask=0x80, i; + int mask = 0x80, i; - for (i=0; i<4; ++i, mask>>=1) { - if (channel & mask) { - if (stbi__at_eof(s)) return stbi__errpuc("bad file","PIC file too short"); - dest[i]=stbi__get8(s); + for (i = 0; i < 4; ++i, mask >>= 1) + { + if (channel & mask) + { + if (stbi__at_eof(s)) + return stbi__errpuc("bad file", "PIC file too short"); + dest[i] = stbi__get8(s); } } return dest; } -static void stbi__copyval(int channel,stbi_uc *dest,const stbi_uc *src) +static void stbi__copyval(int channel, stbi_uc *dest, const stbi_uc *src) { - int mask=0x80,i; + int mask = 0x80, i; - for (i=0;i<4; ++i, mask>>=1) - if (channel&mask) - dest[i]=src[i]; + for (i = 0; i < 4; ++i, mask >>= 1) + if (channel & mask) + dest[i] = src[i]; } -static stbi_uc *stbi__pic_load_core(stbi__context *s,int width,int height,int *comp, stbi_uc *result) +static stbi_uc *stbi__pic_load_core(stbi__context *s, int width, int height, int *comp, stbi_uc *result) { - int act_comp=0,num_packets=0,y,chained; + int act_comp = 0, num_packets = 0, y, chained; stbi__pic_packet packets[10]; // this will (should...) cater for even some bizarre stuff like having data - // for the same channel in multiple packets. - do { + // para the same channel in multiple packets. + do + { stbi__pic_packet *packet; - if (num_packets==sizeof(packets)/sizeof(packets[0])) - return stbi__errpuc("bad format","too many packets"); + if (num_packets == sizeof(packets) / sizeof(packets[0])) + return stbi__errpuc("bad format", "too many packets"); packet = &packets[num_packets++]; chained = stbi__get8(s); - packet->size = stbi__get8(s); - packet->type = stbi__get8(s); + packet->size = stbi__get8(s); + packet->type = stbi__get8(s); packet->channel = stbi__get8(s); act_comp |= packet->channel; - if (stbi__at_eof(s)) return stbi__errpuc("bad file","file too short (reading packets)"); - if (packet->size != 8) return stbi__errpuc("bad format","packet isn't 8bpp"); + if (stbi__at_eof(s)) + return stbi__errpuc("bad file", "file too short (reading packets)"); + if (packet->size != 8) + return stbi__errpuc("bad format", "packet isn't 8bpp"); } while (chained); *comp = (act_comp & 0x10 ? 4 : 3); // has alpha channel? - for(y=0; ytype) { - default: - return stbi__errpuc("bad format","packet has bad compression type"); + switch (packet->type) + { + default: + return stbi__errpuc("bad format", "packet has bad compression type"); - case 0: {//uncompressed - int x; + case 0: + { // uncompressed + int x; - for(x=0;xchannel,dest)) + for (x = 0; x < width; ++x, dest += 4) + if (!stbi__readval(s, packet->channel, dest)) + return 0; + break; + } + + case 1: // Pure RLE + { + int left = width, i; + + while (left > 0) + { + stbi_uc count, value[4]; + + count = stbi__get8(s); + if (stbi__at_eof(s)) + return stbi__errpuc("bad file", "file too short (pure read count)"); + + if (count > left) + count = (stbi_uc)left; + + if (!stbi__readval(s, packet->channel, value)) + return 0; + + for (i = 0; i < count; ++i, dest += 4) + stbi__copyval(packet->channel, dest, value); + left -= count; + } + } + break; + + case 2: + { // Mixed RLE + int left = width; + while (left > 0) + { + int count = stbi__get8(s), i; + if (stbi__at_eof(s)) + return stbi__errpuc("bad file", "file too short (mixed read count)"); + + if (count >= 128) + { // Repeated + stbi_uc value[4]; + + if (count == 128) + count = stbi__get16be(s); + else + count -= 127; + if (count > left) + return stbi__errpuc("bad file", "scanline overrun"); + + if (!stbi__readval(s, packet->channel, value)) return 0; - break; - } - case 1://Pure RLE - { - int left=width, i; - - while (left>0) { - stbi_uc count,value[4]; - - count=stbi__get8(s); - if (stbi__at_eof(s)) return stbi__errpuc("bad file","file too short (pure read count)"); - - if (count > left) - count = (stbi_uc) left; - - if (!stbi__readval(s,packet->channel,value)) return 0; - - for(i=0; ichannel,dest,value); - left -= count; - } + for (i = 0; i < count; ++i, dest += 4) + stbi__copyval(packet->channel, dest, value); } - break; + else + { // Raw + ++count; + if (count > left) + return stbi__errpuc("bad file", "scanline overrun"); - case 2: {//Mixed RLE - int left=width; - while (left>0) { - int count = stbi__get8(s), i; - if (stbi__at_eof(s)) return stbi__errpuc("bad file","file too short (mixed read count)"); - - if (count >= 128) { // Repeated - stbi_uc value[4]; - - if (count==128) - count = stbi__get16be(s); - else - count -= 127; - if (count > left) - return stbi__errpuc("bad file","scanline overrun"); - - if (!stbi__readval(s,packet->channel,value)) + for (i = 0; i < count; ++i, dest += 4) + if (!stbi__readval(s, packet->channel, dest)) return 0; - - for(i=0;ichannel,dest,value); - } else { // Raw - ++count; - if (count>left) return stbi__errpuc("bad file","scanline overrun"); - - for(i=0;ichannel,dest)) - return 0; - } - left-=count; } - break; + left -= count; } + break; + } } } } @@ -6497,43 +7620,51 @@ static stbi_uc *stbi__pic_load_core(stbi__context *s,int width,int height,int *c return result; } -static void *stbi__pic_load(stbi__context *s,int *px,int *py,int *comp,int req_comp, stbi__result_info *ri) +static void *stbi__pic_load(stbi__context *s, int *px, int *py, int *comp, int req_comp, stbi__result_info *ri) { stbi_uc *result; - int i, x,y, internal_comp; + int i, x, y, internal_comp; STBI_NOTUSED(ri); - if (!comp) comp = &internal_comp; + if (!comp) + comp = &internal_comp; - for (i=0; i<92; ++i) + for (i = 0; i < 92; ++i) stbi__get8(s); x = stbi__get16be(s); y = stbi__get16be(s); - if (y > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large","Very large image (corrupt?)"); - if (x > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large","Very large image (corrupt?)"); + if (y > STBI_MAX_DIMENSIONS) + return stbi__errpuc("too large", "Very large image (corrupt?)"); + if (x > STBI_MAX_DIMENSIONS) + return stbi__errpuc("too large", "Very large image (corrupt?)"); - if (stbi__at_eof(s)) return stbi__errpuc("bad file","file too short (pic header)"); - if (!stbi__mad3sizes_valid(x, y, 4, 0)) return stbi__errpuc("too large", "PIC image too large to decode"); + if (stbi__at_eof(s)) + return stbi__errpuc("bad file", "file too short (pic header)"); + if (!stbi__mad3sizes_valid(x, y, 4, 0)) + return stbi__errpuc("too large", "PIC image too large to decode"); - stbi__get32be(s); //skip `ratio' - stbi__get16be(s); //skip `fields' - stbi__get16be(s); //skip `pad' + stbi__get32be(s); // skip `ratio' + stbi__get16be(s); // skip `fields' + stbi__get16be(s); // skip `pad' // intermediate buffer is RGBA - result = (stbi_uc *) stbi__malloc_mad3(x, y, 4, 0); - if (!result) return stbi__errpuc("outofmem", "Out of memory"); - memset(result, 0xff, x*y*4); + result = (stbi_uc *)stbi__malloc_mad3(x, y, 4, 0); + if (!result) + return stbi__errpuc("outofmem", "Out of memory"); + memset(result, 0xff, x * y * 4); - if (!stbi__pic_load_core(s,x,y,comp, result)) { + if (!stbi__pic_load_core(s, x, y, comp, result)) + { STBI_FREE(result); - result=0; + result = 0; } *px = x; *py = y; - if (req_comp == 0) req_comp = *comp; - result=stbi__convert_format(result,4,req_comp,x,y); + if (req_comp == 0) + req_comp = *comp; + result = stbi__convert_format(result, 4, req_comp, x, y); return result; } @@ -6559,12 +7690,12 @@ typedef struct typedef struct { - int w,h; - stbi_uc *out; // output buffer (always 4 components) - stbi_uc *background; // The current "background" as far as a gif is concerned + int w, h; + stbi_uc *out; // output buffer (always 4 components) + stbi_uc *background; // The current "background" as far as a gif is concerned stbi_uc *history; int flags, bgindex, ratio, transparent, eflags; - stbi_uc pal[256][4]; + stbi_uc pal[256][4]; stbi_uc lpal[256][4]; stbi__gif_lzw codes[8192]; stbi_uc *color_table; @@ -6580,10 +7711,13 @@ typedef struct static int stbi__gif_test_raw(stbi__context *s) { int sz; - if (stbi__get8(s) != 'G' || stbi__get8(s) != 'I' || stbi__get8(s) != 'F' || stbi__get8(s) != '8') return 0; + if (stbi__get8(s) != 'G' || stbi__get8(s) != 'I' || stbi__get8(s) != 'F' || stbi__get8(s) != '8') + return 0; sz = stbi__get8(s); - if (sz != '9' && sz != '7') return 0; - if (stbi__get8(s) != 'a') return 0; + if (sz != '9' && sz != '7') + return 0; + if (stbi__get8(s) != 'a') + return 0; return 1; } @@ -6597,7 +7731,8 @@ static int stbi__gif_test(stbi__context *s) static void stbi__gif_parse_colortable(stbi__context *s, stbi_uc pal[256][4], int num_entries, int transp) { int i; - for (i=0; i < num_entries; ++i) { + for (i = 0; i < num_entries; ++i) + { pal[i][2] = stbi__get8(s); pal[i][1] = stbi__get8(s); pal[i][0] = stbi__get8(s); @@ -6612,8 +7747,10 @@ static int stbi__gif_header(stbi__context *s, stbi__gif *g, int *comp, int is_in return stbi__err("not GIF", "Corrupt GIF"); version = stbi__get8(s); - if (version != '7' && version != '9') return stbi__err("not GIF", "Corrupt GIF"); - if (stbi__get8(s) != 'a') return stbi__err("not GIF", "Corrupt GIF"); + if (version != '7' && version != '9') + return stbi__err("not GIF", "Corrupt GIF"); + if (stbi__get8(s) != 'a') + return stbi__err("not GIF", "Corrupt GIF"); stbi__g_failure_reason = ""; g->w = stbi__get16le(s); @@ -6623,30 +7760,38 @@ static int stbi__gif_header(stbi__context *s, stbi__gif *g, int *comp, int is_in g->ratio = stbi__get8(s); g->transparent = -1; - if (g->w > STBI_MAX_DIMENSIONS) return stbi__err("too large","Very large image (corrupt?)"); - if (g->h > STBI_MAX_DIMENSIONS) return stbi__err("too large","Very large image (corrupt?)"); + if (g->w > STBI_MAX_DIMENSIONS) + return stbi__err("too large", "Very large image (corrupt?)"); + if (g->h > STBI_MAX_DIMENSIONS) + return stbi__err("too large", "Very large image (corrupt?)"); - if (comp != 0) *comp = 4; // can't actually tell whether it's 3 or 4 until we parse the comments + if (comp != 0) + *comp = 4; // can't actually tell whether it's 3 or 4 until we parse the comments - if (is_info) return 1; + if (is_info) + return 1; if (g->flags & 0x80) - stbi__gif_parse_colortable(s,g->pal, 2 << (g->flags & 7), -1); + stbi__gif_parse_colortable(s, g->pal, 2 << (g->flags & 7), -1); return 1; } static int stbi__gif_info_raw(stbi__context *s, int *x, int *y, int *comp) { - stbi__gif* g = (stbi__gif*) stbi__malloc(sizeof(stbi__gif)); - if (!g) return stbi__err("outofmem", "Out of memory"); - if (!stbi__gif_header(s, g, comp, 1)) { + stbi__gif *g = (stbi__gif *)stbi__malloc(sizeof(stbi__gif)); + if (!g) + return stbi__err("outofmem", "Out of memory"); + if (!stbi__gif_header(s, g, comp, 1)) + { STBI_FREE(g); - stbi__rewind( s ); + stbi__rewind(s); return 0; } - if (x) *x = g->w; - if (y) *y = g->h; + if (x) + *x = g->w; + if (y) + *y = g->h; STBI_FREE(g); return 1; } @@ -6661,14 +7806,16 @@ static void stbi__out_gif_code(stbi__gif *g, stbi__uint16 code) if (g->codes[code].prefix >= 0) stbi__out_gif_code(g, g->codes[code].prefix); - if (g->cur_y >= g->max_y) return; + if (g->cur_y >= g->max_y) + return; idx = g->cur_x + g->cur_y; p = &g->out[idx]; g->history[idx / 4] = 1; c = &g->color_table[g->codes[code].suffix * 4]; - if (c[3] > 128) { // don't render transparent pixels; + if (c[3] > 128) + { // don't render transparent pixels; p[0] = c[2]; p[1] = c[1]; p[2] = c[0]; @@ -6676,11 +7823,13 @@ static void stbi__out_gif_code(stbi__gif *g, stbi__uint16 code) } g->cur_x += 4; - if (g->cur_x >= g->max_x) { + if (g->cur_x >= g->max_x) + { g->cur_x = g->start_x; g->cur_y += g->step; - while (g->cur_y >= g->max_y && g->parse > 0) { + while (g->cur_y >= g->max_y && g->parse > 0) + { g->step = (1 << g->parse) * g->line_size; g->cur_y = g->start_y + (g->step >> 1); --g->parse; @@ -6697,76 +7846,95 @@ static stbi_uc *stbi__process_gif_raster(stbi__context *s, stbi__gif *g) stbi__gif_lzw *p; lzw_cs = stbi__get8(s); - if (lzw_cs > 12) return NULL; + if (lzw_cs > 12) + return NULL; clear = 1 << lzw_cs; first = 1; codesize = lzw_cs + 1; codemask = (1 << codesize) - 1; bits = 0; valid_bits = 0; - for (init_code = 0; init_code < clear; init_code++) { + for (init_code = 0; init_code < clear; init_code++) + { g->codes[init_code].prefix = -1; - g->codes[init_code].first = (stbi_uc) init_code; - g->codes[init_code].suffix = (stbi_uc) init_code; + g->codes[init_code].first = (stbi_uc)init_code; + g->codes[init_code].suffix = (stbi_uc)init_code; } // support no starting clear code - avail = clear+2; + avail = clear + 2; oldcode = -1; len = 0; - for(;;) { - if (valid_bits < codesize) { - if (len == 0) { + for (;;) + { + if (valid_bits < codesize) + { + if (len == 0) + { len = stbi__get8(s); // start new block if (len == 0) return g->out; } --len; - bits |= (stbi__int32) stbi__get8(s) << valid_bits; + bits |= (stbi__int32)stbi__get8(s) << valid_bits; valid_bits += 8; - } else { + } + else + { stbi__int32 code = bits & codemask; bits >>= codesize; valid_bits -= codesize; // @OPTIMIZE: is there some way we can accelerate the non-clear path? - if (code == clear) { // clear code + if (code == clear) + { // clear code codesize = lzw_cs + 1; codemask = (1 << codesize) - 1; avail = clear + 2; oldcode = -1; first = 0; - } else if (code == clear + 1) { // end of stream code + } + else if (code == clear + 1) + { // end of stream code stbi__skip(s, len); while ((len = stbi__get8(s)) > 0) - stbi__skip(s,len); + stbi__skip(s, len); return g->out; - } else if (code <= avail) { - if (first) { + } + else if (code <= avail) + { + if (first) + { return stbi__errpuc("no clear code", "Corrupt GIF"); } - if (oldcode >= 0) { + if (oldcode >= 0) + { p = &g->codes[avail++]; - if (avail > 8192) { + if (avail > 8192) + { return stbi__errpuc("too many codes", "Corrupt GIF"); } - p->prefix = (stbi__int16) oldcode; + p->prefix = (stbi__int16)oldcode; p->first = g->codes[oldcode].first; p->suffix = (code == avail) ? p->first : g->codes[code].first; - } else if (code == avail) + } + else if (code == avail) return stbi__errpuc("illegal code in raster", "Corrupt GIF"); - stbi__out_gif_code(g, (stbi__uint16) code); + stbi__out_gif_code(g, (stbi__uint16)code); - if ((avail & codemask) == 0 && avail <= 0x0FFF) { + if ((avail & codemask) == 0 && avail <= 0x0FFF) + { codesize++; codemask = (1 << codesize) - 1; } oldcode = code; - } else { + } + else + { return stbi__errpuc("illegal code in raster", "Corrupt GIF"); } } @@ -6785,14 +7953,16 @@ static stbi_uc *stbi__gif_load_next(stbi__context *s, stbi__gif *g, int *comp, i // on first frame, any non-written pixels get the background colour (non-transparent) first_frame = 0; - if (g->out == 0) { - if (!stbi__gif_header(s, g, comp,0)) return 0; // stbi__g_failure_reason set by stbi__gif_header + if (g->out == 0) + { + if (!stbi__gif_header(s, g, comp, 0)) + return 0; // stbi__g_failure_reason set by stbi__gif_header if (!stbi__mad3sizes_valid(4, g->w, g->h, 0)) return stbi__errpuc("too large", "GIF image is too large"); pcount = g->w * g->h; - g->out = (stbi_uc *) stbi__malloc(4 * pcount); - g->background = (stbi_uc *) stbi__malloc(4 * pcount); - g->history = (stbi_uc *) stbi__malloc(pcount); + g->out = (stbi_uc *)stbi__malloc(4 * pcount); + g->background = (stbi_uc *)stbi__malloc(4 * pcount); + g->history = (stbi_uc *)stbi__malloc(pcount); if (!g->out || !g->background || !g->history) return stbi__errpuc("outofmem", "Out of memory"); @@ -6803,29 +7973,41 @@ static stbi_uc *stbi__gif_load_next(stbi__context *s, stbi__gif *g, int *comp, i memset(g->background, 0x00, 4 * pcount); // state of the background (starts transparent) memset(g->history, 0x00, pcount); // pixels that were affected previous frame first_frame = 1; - } else { + } + else + { // second frame - how do we dispose of the previous one? dispose = (g->eflags & 0x1C) >> 2; pcount = g->w * g->h; - if ((dispose == 3) && (two_back == 0)) { + if ((dispose == 3) && (two_back == 0)) + { dispose = 2; // if I don't have an image to revert back to, default to the old background } - if (dispose == 3) { // use previous graphic - for (pi = 0; pi < pcount; ++pi) { - if (g->history[pi]) { - memcpy( &g->out[pi * 4], &two_back[pi * 4], 4 ); + if (dispose == 3) + { // use previous graphic + for (pi = 0; pi < pcount; ++pi) + { + if (g->history[pi]) + { + memcpy(&g->out[pi * 4], &two_back[pi * 4], 4); } } - } else if (dispose == 2) { + } + else if (dispose == 2) + { // restore what was changed last frame to background before that frame; - for (pi = 0; pi < pcount; ++pi) { - if (g->history[pi]) { - memcpy( &g->out[pi * 4], &g->background[pi * 4], 4 ); + for (pi = 0; pi < pcount; ++pi) + { + if (g->history[pi]) + { + memcpy(&g->out[pi * 4], &g->background[pi * 4], 4); } } - } else { + } + else + { // This is a non-disposal case eithe way, so just // leave the pixels as is, and they will become the new background // 1: do not dispose @@ -6833,118 +8015,141 @@ static stbi_uc *stbi__gif_load_next(stbi__context *s, stbi__gif *g, int *comp, i } // background is what out is after the undoing of the previou frame; - memcpy( g->background, g->out, 4 * g->w * g->h ); + memcpy(g->background, g->out, 4 * g->w * g->h); } // clear my history; - memset( g->history, 0x00, g->w * g->h ); // pixels that were affected previous frame + memset(g->history, 0x00, g->w * g->h); // pixels that were affected previous frame - for (;;) { + for (;;) + { int tag = stbi__get8(s); - switch (tag) { - case 0x2C: /* Image Descriptor */ + switch (tag) + { + case 0x2C: /* Image Descriptor */ + { + stbi__int32 x, y, w, h; + stbi_uc *o; + + x = stbi__get16le(s); + y = stbi__get16le(s); + w = stbi__get16le(s); + h = stbi__get16le(s); + if (((x + w) > (g->w)) || ((y + h) > (g->h))) + return stbi__errpuc("bad Image Descriptor", "Corrupt GIF"); + + g->line_size = g->w * 4; + g->start_x = x * 4; + g->start_y = y * g->line_size; + g->max_x = g->start_x + w * 4; + g->max_y = g->start_y + h * g->line_size; + g->cur_x = g->start_x; + g->cur_y = g->start_y; + + // if the width of the specified rectangle is 0, that means + // we may not see *any* pixels or the image is malformed; + // to make sure this is caught, move the current y down to + // max_y (which is what out_gif_code checks). + if (w == 0) + g->cur_y = g->max_y; + + g->lflags = stbi__get8(s); + + if (g->lflags & 0x40) { - stbi__int32 x, y, w, h; - stbi_uc *o; - - x = stbi__get16le(s); - y = stbi__get16le(s); - w = stbi__get16le(s); - h = stbi__get16le(s); - if (((x + w) > (g->w)) || ((y + h) > (g->h))) - return stbi__errpuc("bad Image Descriptor", "Corrupt GIF"); - - g->line_size = g->w * 4; - g->start_x = x * 4; - g->start_y = y * g->line_size; - g->max_x = g->start_x + w * 4; - g->max_y = g->start_y + h * g->line_size; - g->cur_x = g->start_x; - g->cur_y = g->start_y; - - // if the width of the specified rectangle is 0, that means - // we may not see *any* pixels or the image is malformed; - // to make sure this is caught, move the current y down to - // max_y (which is what out_gif_code checks). - if (w == 0) - g->cur_y = g->max_y; - - g->lflags = stbi__get8(s); - - if (g->lflags & 0x40) { - g->step = 8 * g->line_size; // first interlaced spacing - g->parse = 3; - } else { - g->step = g->line_size; - g->parse = 0; - } - - if (g->lflags & 0x80) { - stbi__gif_parse_colortable(s,g->lpal, 2 << (g->lflags & 7), g->eflags & 0x01 ? g->transparent : -1); - g->color_table = (stbi_uc *) g->lpal; - } else if (g->flags & 0x80) { - g->color_table = (stbi_uc *) g->pal; - } else - return stbi__errpuc("missing color table", "Corrupt GIF"); - - o = stbi__process_gif_raster(s, g); - if (!o) return NULL; - - // if this was the first frame, - pcount = g->w * g->h; - if (first_frame && (g->bgindex > 0)) { - // if first frame, any pixel not drawn to gets the background color - for (pi = 0; pi < pcount; ++pi) { - if (g->history[pi] == 0) { - g->pal[g->bgindex][3] = 255; // just in case it was made transparent, undo that; It will be reset next frame if need be; - memcpy( &g->out[pi * 4], &g->pal[g->bgindex], 4 ); - } - } - } - - return o; + g->step = 8 * g->line_size; // first interlaced spacing + g->parse = 3; + } + else + { + g->step = g->line_size; + g->parse = 0; } - case 0x21: // Comment Extension. + if (g->lflags & 0x80) { - int len; - int ext = stbi__get8(s); - if (ext == 0xF9) { // Graphic Control Extension. - len = stbi__get8(s); - if (len == 4) { - g->eflags = stbi__get8(s); - g->delay = 10 * stbi__get16le(s); // delay - 1/100th of a second, saving as 1/1000ths. + stbi__gif_parse_colortable(s, g->lpal, 2 << (g->lflags & 7), g->eflags & 0x01 ? g->transparent : -1); + g->color_table = (stbi_uc *)g->lpal; + } + else if (g->flags & 0x80) + { + g->color_table = (stbi_uc *)g->pal; + } + else + return stbi__errpuc("missing color table", "Corrupt GIF"); - // unset old transparent - if (g->transparent >= 0) { - g->pal[g->transparent][3] = 255; - } - if (g->eflags & 0x01) { - g->transparent = stbi__get8(s); - if (g->transparent >= 0) { - g->pal[g->transparent][3] = 0; - } - } else { - // don't need transparent - stbi__skip(s, 1); - g->transparent = -1; - } - } else { - stbi__skip(s, len); - break; + o = stbi__process_gif_raster(s, g); + if (!o) + return NULL; + + // if this was the first frame, + pcount = g->w * g->h; + if (first_frame && (g->bgindex > 0)) + { + // if first frame, any pixel not drawn to gets the background color + for (pi = 0; pi < pcount; ++pi) + { + if (g->history[pi] == 0) + { + g->pal[g->bgindex][3] = 255; // just in case it was made transparent, undo that; It will be reset next frame if need be; + memcpy(&g->out[pi * 4], &g->pal[g->bgindex], 4); } } - while ((len = stbi__get8(s)) != 0) { + } + + return o; + } + + case 0x21: // Comment Extension. + { + int len; + int ext = stbi__get8(s); + if (ext == 0xF9) + { // Graphic Control Extension. + len = stbi__get8(s); + if (len == 4) + { + g->eflags = stbi__get8(s); + g->delay = 10 * stbi__get16le(s); // delay - 1/100th of a second, saving as 1/1000ths. + + // unset old transparent + if (g->transparent >= 0) + { + g->pal[g->transparent][3] = 255; + } + if (g->eflags & 0x01) + { + g->transparent = stbi__get8(s); + if (g->transparent >= 0) + { + g->pal[g->transparent][3] = 0; + } + } + else + { + // don't need transparent + stbi__skip(s, 1); + g->transparent = -1; + } + } + else + { stbi__skip(s, len); + break; } - break; } + while ((len = stbi__get8(s)) != 0) + { + stbi__skip(s, len); + } + break; + } - case 0x3B: // gif stream termination code - return (stbi_uc *) s; // using '1' causes warning on some compilers + case 0x3B: // gif stream termination code + return (stbi_uc *)s; // using '1' causes warning on some compilers - default: - return stbi__errpuc("unknown code", "Corrupt GIF"); + default: + return stbi__errpuc("unknown code", "Corrupt GIF"); } } } @@ -6955,14 +8160,17 @@ static void *stbi__load_gif_main_outofmem(stbi__gif *g, stbi_uc *out, int **dela STBI_FREE(g->history); STBI_FREE(g->background); - if (out) STBI_FREE(out); - if (delays && *delays) STBI_FREE(*delays); + if (out) + STBI_FREE(out); + if (delays && *delays) + STBI_FREE(*delays); return stbi__errpuc("outofmem", "Out of memory"); } static void *stbi__load_gif_main(stbi__context *s, int **delays, int *x, int *y, int *z, int *comp, int req_comp) { - if (stbi__gif_test(s)) { + if (stbi__gif_test(s)) + { int layers = 0; stbi_uc *u = 0; stbi_uc *out = 0; @@ -6976,54 +8184,66 @@ static void *stbi__load_gif_main(stbi__context *s, int **delays, int *x, int *y, STBI_NOTUSED(delays_size); memset(&g, 0, sizeof(g)); - if (delays) { + if (delays) + { *delays = 0; } - do { + do + { u = stbi__gif_load_next(s, &g, comp, req_comp, two_back); - if (u == (stbi_uc *) s) u = 0; // end of animated gif marker + if (u == (stbi_uc *)s) + u = 0; // end of animated gif marker - if (u) { + if (u) + { *x = g.w; *y = g.h; ++layers; stride = g.w * g.h * 4; - if (out) { - void *tmp = (stbi_uc*) STBI_REALLOC_SIZED( out, out_size, layers * stride ); + if (out) + { + void *tmp = (stbi_uc *)STBI_REALLOC_SIZED(out, out_size, layers * stride); if (!tmp) return stbi__load_gif_main_outofmem(&g, out, delays); - else { - out = (stbi_uc*) tmp; - out_size = layers * stride; + else + { + out = (stbi_uc *)tmp; + out_size = layers * stride; } - if (delays) { - int *new_delays = (int*) STBI_REALLOC_SIZED( *delays, delays_size, sizeof(int) * layers ); + if (delays) + { + int *new_delays = (int *)STBI_REALLOC_SIZED(*delays, delays_size, sizeof(int) * layers); if (!new_delays) return stbi__load_gif_main_outofmem(&g, out, delays); *delays = new_delays; delays_size = layers * sizeof(int); } - } else { - out = (stbi_uc*)stbi__malloc( layers * stride ); + } + else + { + out = (stbi_uc *)stbi__malloc(layers * stride); if (!out) return stbi__load_gif_main_outofmem(&g, out, delays); out_size = layers * stride; - if (delays) { - *delays = (int*) stbi__malloc( layers * sizeof(int) ); + if (delays) + { + *delays = (int *)stbi__malloc(layers * sizeof(int)); if (!*delays) return stbi__load_gif_main_outofmem(&g, out, delays); delays_size = layers * sizeof(int); } } - memcpy( out + ((layers - 1) * stride), u, stride ); - if (layers >= 2) { + memcpy(out + ((layers - 1) * stride), u, stride); + if (layers >= 2) + { two_back = out - 2 * stride; } - if (delays) { + if (delays) + { (*delays)[layers - 1U] = g.delay; } } @@ -7040,7 +8260,9 @@ static void *stbi__load_gif_main(stbi__context *s, int **delays, int *x, int *y, *z = layers; return out; - } else { + } + else + { return stbi__errpuc("not GIF", "Image was not as a gif type."); } } @@ -7053,8 +8275,10 @@ static void *stbi__gif_load(stbi__context *s, int *x, int *y, int *comp, int req STBI_NOTUSED(ri); u = stbi__gif_load_next(s, &g, comp, req_comp, 0); - if (u == (stbi_uc *) s) u = 0; // end of animated gif marker - if (u) { + if (u == (stbi_uc *)s) + u = 0; // end of animated gif marker + if (u) + { *x = g.w; *y = g.h; @@ -7062,7 +8286,9 @@ static void *stbi__gif_load(stbi__context *s, int *x, int *y, int *comp, int req // can be done for multiple frames. if (req_comp && req_comp != 4) u = stbi__convert_format(u, 4, req_comp, g.w, g.h); - } else if (g.out) { + } + else if (g.out) + { // if there was an error and we allocated an image buffer, free it! STBI_FREE(g.out); } @@ -7076,7 +8302,7 @@ static void *stbi__gif_load(stbi__context *s, int *x, int *y, int *comp, int req static int stbi__gif_info(stbi__context *s, int *x, int *y, int *comp) { - return stbi__gif_info_raw(s,x,y,comp); + return stbi__gif_info_raw(s, x, y, comp); } #endif @@ -7087,41 +8313,44 @@ static int stbi__gif_info(stbi__context *s, int *x, int *y, int *comp) static int stbi__hdr_test_core(stbi__context *s, const char *signature) { int i; - for (i=0; signature[i]; ++i) + for (i = 0; signature[i]; ++i) if (stbi__get8(s) != signature[i]) - return 0; + return 0; stbi__rewind(s); return 1; } -static int stbi__hdr_test(stbi__context* s) +static int stbi__hdr_test(stbi__context *s) { int r = stbi__hdr_test_core(s, "#?RADIANCE\n"); stbi__rewind(s); - if(!r) { - r = stbi__hdr_test_core(s, "#?RGBE\n"); - stbi__rewind(s); + if (!r) + { + r = stbi__hdr_test_core(s, "#?RGBE\n"); + stbi__rewind(s); } return r; } -#define STBI__HDR_BUFLEN 1024 +#define STBI__HDR_BUFLEN 1024 static char *stbi__hdr_gettoken(stbi__context *z, char *buffer) { - int len=0; + int len = 0; char c = '\0'; - c = (char) stbi__get8(z); + c = (char)stbi__get8(z); - while (!stbi__at_eof(z) && c != '\n') { + while (!stbi__at_eof(z) && c != '\n') + { buffer[len++] = c; - if (len == STBI__HDR_BUFLEN-1) { + if (len == STBI__HDR_BUFLEN - 1) + { // flush to end of line while (!stbi__at_eof(z) && stbi__get8(z) != '\n') ; break; } - c = (char) stbi__get8(z); + c = (char)stbi__get8(z); } buffer[len] = 0; @@ -7130,27 +8359,38 @@ static char *stbi__hdr_gettoken(stbi__context *z, char *buffer) static void stbi__hdr_convert(float *output, stbi_uc *input, int req_comp) { - if ( input[3] != 0 ) { + if (input[3] != 0) + { float f1; // Exponent - f1 = (float) ldexp(1.0f, input[3] - (int)(128 + 8)); + f1 = (float)ldexp(1.0f, input[3] - (int)(128 + 8)); if (req_comp <= 2) output[0] = (input[0] + input[1] + input[2]) * f1 / 3; - else { + else + { output[0] = input[0] * f1; output[1] = input[1] * f1; output[2] = input[2] * f1; } - if (req_comp == 2) output[1] = 1; - if (req_comp == 4) output[3] = 1; - } else { - switch (req_comp) { - case 4: output[3] = 1; /* fallthrough */ - case 3: output[0] = output[1] = output[2] = 0; - break; - case 2: output[1] = 1; /* fallthrough */ - case 1: output[0] = 0; - break; + if (req_comp == 2) + output[1] = 1; + if (req_comp == 4) + output[3] = 1; + } + else + { + switch (req_comp) + { + case 4: + output[3] = 1; /* fallthrough */ + case 3: + output[0] = output[1] = output[2] = 0; + break; + case 2: + output[1] = 1; /* fallthrough */ + case 1: + output[0] = 0; + break; } } } @@ -7165,80 +8405,98 @@ static float *stbi__hdr_load(stbi__context *s, int *x, int *y, int *comp, int re float *hdr_data; int len; unsigned char count, value; - int i, j, k, c1,c2, z; + int i, j, k, c1, c2, z; const char *headerToken; STBI_NOTUSED(ri); // Check identifier - headerToken = stbi__hdr_gettoken(s,buffer); + headerToken = stbi__hdr_gettoken(s, buffer); if (strcmp(headerToken, "#?RADIANCE") != 0 && strcmp(headerToken, "#?RGBE") != 0) return stbi__errpf("not HDR", "Corrupt HDR image"); // Parse header - for(;;) { - token = stbi__hdr_gettoken(s,buffer); - if (token[0] == 0) break; - if (strcmp(token, "FORMAT=32-bit_rle_rgbe") == 0) valid = 1; + for (;;) + { + token = stbi__hdr_gettoken(s, buffer); + if (token[0] == 0) + break; + if (strcmp(token, "FORMAT=32-bit_rle_rgbe") == 0) + valid = 1; } - if (!valid) return stbi__errpf("unsupported format", "Unsupported HDR format"); + if (!valid) + return stbi__errpf("unsupported format", "Unsupported HDR format"); // Parse width and height // can't use sscanf() if we're not using stdio! - token = stbi__hdr_gettoken(s,buffer); - if (strncmp(token, "-Y ", 3)) return stbi__errpf("unsupported data layout", "Unsupported HDR format"); + token = stbi__hdr_gettoken(s, buffer); + if (strncmp(token, "-Y ", 3)) + return stbi__errpf("unsupported data layout", "Unsupported HDR format"); token += 3; - height = (int) strtol(token, &token, 10); - while (*token == ' ') ++token; - if (strncmp(token, "+X ", 3)) return stbi__errpf("unsupported data layout", "Unsupported HDR format"); + height = (int)strtol(token, &token, 10); + while (*token == ' ') + ++token; + if (strncmp(token, "+X ", 3)) + return stbi__errpf("unsupported data layout", "Unsupported HDR format"); token += 3; - width = (int) strtol(token, NULL, 10); + width = (int)strtol(token, NULL, 10); - if (height > STBI_MAX_DIMENSIONS) return stbi__errpf("too large","Very large image (corrupt?)"); - if (width > STBI_MAX_DIMENSIONS) return stbi__errpf("too large","Very large image (corrupt?)"); + if (height > STBI_MAX_DIMENSIONS) + return stbi__errpf("too large", "Very large image (corrupt?)"); + if (width > STBI_MAX_DIMENSIONS) + return stbi__errpf("too large", "Very large image (corrupt?)"); *x = width; *y = height; - if (comp) *comp = 3; - if (req_comp == 0) req_comp = 3; + if (comp) + *comp = 3; + if (req_comp == 0) + req_comp = 3; if (!stbi__mad4sizes_valid(width, height, req_comp, sizeof(float), 0)) return stbi__errpf("too large", "HDR image is too large"); // Read data - hdr_data = (float *) stbi__malloc_mad4(width, height, req_comp, sizeof(float), 0); + hdr_data = (float *)stbi__malloc_mad4(width, height, req_comp, sizeof(float), 0); if (!hdr_data) return stbi__errpf("outofmem", "Out of memory"); // Load image data // image data is stored as some number of sca - if ( width < 8 || width >= 32768) { + if (width < 8 || width >= 32768) + { // Read flat data - for (j=0; j < height; ++j) { - for (i=0; i < width; ++i) { + for (j = 0; j < height; ++j) + { + for (i = 0; i < width; ++i) + { stbi_uc rgbe[4]; - main_decode_loop: + main_decode_loop: stbi__getn(s, rgbe, 4); stbi__hdr_convert(hdr_data + j * width * req_comp + i * req_comp, rgbe, req_comp); } } - } else { + } + else + { // Read RLE-encoded data scanline = NULL; - for (j = 0; j < height; ++j) { + for (j = 0; j < height; ++j) + { c1 = stbi__get8(s); c2 = stbi__get8(s); len = stbi__get8(s); - if (c1 != 2 || c2 != 2 || (len & 0x80)) { + if (c1 != 2 || c2 != 2 || (len & 0x80)) + { // not run-length encoded, so we have to actually use THIS data as a decoded // pixel (note this can't be a valid pixel--one of RGB must be >= 128) stbi_uc rgbe[4]; - rgbe[0] = (stbi_uc) c1; - rgbe[1] = (stbi_uc) c2; - rgbe[2] = (stbi_uc) len; - rgbe[3] = (stbi_uc) stbi__get8(s); + rgbe[0] = (stbi_uc)c1; + rgbe[1] = (stbi_uc)c2; + rgbe[2] = (stbi_uc)len; + rgbe[3] = (stbi_uc)stbi__get8(s); stbi__hdr_convert(hdr_data, rgbe, req_comp); i = 1; j = 0; @@ -7247,37 +8505,59 @@ static float *stbi__hdr_load(stbi__context *s, int *x, int *y, int *comp, int re } len <<= 8; len |= stbi__get8(s); - if (len != width) { STBI_FREE(hdr_data); STBI_FREE(scanline); return stbi__errpf("invalid decoded scanline length", "corrupt HDR"); } - if (scanline == NULL) { - scanline = (stbi_uc *) stbi__malloc_mad2(width, 4, 0); - if (!scanline) { + if (len != width) + { + STBI_FREE(hdr_data); + STBI_FREE(scanline); + return stbi__errpf("invalid decoded scanline length", "corrupt HDR"); + } + if (scanline == NULL) + { + scanline = (stbi_uc *)stbi__malloc_mad2(width, 4, 0); + if (!scanline) + { STBI_FREE(hdr_data); return stbi__errpf("outofmem", "Out of memory"); } } - for (k = 0; k < 4; ++k) { + for (k = 0; k < 4; ++k) + { int nleft; i = 0; - while ((nleft = width - i) > 0) { + while ((nleft = width - i) > 0) + { count = stbi__get8(s); - if (count > 128) { + if (count > 128) + { // Run value = stbi__get8(s); count -= 128; - if ((count == 0) || (count > nleft)) { STBI_FREE(hdr_data); STBI_FREE(scanline); return stbi__errpf("corrupt", "bad RLE data in HDR"); } + if ((count == 0) || (count > nleft)) + { + STBI_FREE(hdr_data); + STBI_FREE(scanline); + return stbi__errpf("corrupt", "bad RLE data in HDR"); + } for (z = 0; z < count; ++z) scanline[i++ * 4 + k] = value; - } else { + } + else + { // Dump - if ((count == 0) || (count > nleft)) { STBI_FREE(hdr_data); STBI_FREE(scanline); return stbi__errpf("corrupt", "bad RLE data in HDR"); } + if ((count == 0) || (count > nleft)) + { + STBI_FREE(hdr_data); + STBI_FREE(scanline); + return stbi__errpf("corrupt", "bad RLE data in HDR"); + } for (z = 0; z < count; ++z) scanline[i++ * 4 + k] = stbi__get8(s); } } } - for (i=0; i < width; ++i) - stbi__hdr_convert(hdr_data+(j*width + i)*req_comp, scanline + i*4, req_comp); + for (i = 0; i < width; ++i) + stbi__hdr_convert(hdr_data + (j * width + i) * req_comp, scanline + i * 4, req_comp); } if (scanline) STBI_FREE(scanline); @@ -7293,39 +8573,50 @@ static int stbi__hdr_info(stbi__context *s, int *x, int *y, int *comp) int valid = 0; int dummy; - if (!x) x = &dummy; - if (!y) y = &dummy; - if (!comp) comp = &dummy; + if (!x) + x = &dummy; + if (!y) + y = &dummy; + if (!comp) + comp = &dummy; - if (stbi__hdr_test(s) == 0) { - stbi__rewind( s ); - return 0; + if (stbi__hdr_test(s) == 0) + { + stbi__rewind(s); + return 0; } - for(;;) { - token = stbi__hdr_gettoken(s,buffer); - if (token[0] == 0) break; - if (strcmp(token, "FORMAT=32-bit_rle_rgbe") == 0) valid = 1; + for (;;) + { + token = stbi__hdr_gettoken(s, buffer); + if (token[0] == 0) + break; + if (strcmp(token, "FORMAT=32-bit_rle_rgbe") == 0) + valid = 1; } - if (!valid) { - stbi__rewind( s ); - return 0; + if (!valid) + { + stbi__rewind(s); + return 0; } - token = stbi__hdr_gettoken(s,buffer); - if (strncmp(token, "-Y ", 3)) { - stbi__rewind( s ); - return 0; + token = stbi__hdr_gettoken(s, buffer); + if (strncmp(token, "-Y ", 3)) + { + stbi__rewind(s); + return 0; } token += 3; - *y = (int) strtol(token, &token, 10); - while (*token == ' ') ++token; - if (strncmp(token, "+X ", 3)) { - stbi__rewind( s ); - return 0; + *y = (int)strtol(token, &token, 10); + while (*token == ' ') + ++token; + if (strncmp(token, "+X ", 3)) + { + stbi__rewind(s); + return 0; } token += 3; - *x = (int) strtol(token, NULL, 10); + *x = (int)strtol(token, NULL, 10); *comp = 3; return 1; } @@ -7339,13 +8630,17 @@ static int stbi__bmp_info(stbi__context *s, int *x, int *y, int *comp) info.all_a = 255; p = stbi__bmp_parse_header(s, &info); - if (p == NULL) { - stbi__rewind( s ); + if (p == NULL) + { + stbi__rewind(s); return 0; } - if (x) *x = s->img_x; - if (y) *y = s->img_y; - if (comp) { + if (x) + *x = s->img_x; + if (y) + *y = s->img_y; + if (comp) + { if (info.bpp == 24 && info.ma == 0xff000000) *comp = 3; else @@ -7359,33 +8654,41 @@ static int stbi__bmp_info(stbi__context *s, int *x, int *y, int *comp) static int stbi__psd_info(stbi__context *s, int *x, int *y, int *comp) { int channelCount, dummy, depth; - if (!x) x = &dummy; - if (!y) y = &dummy; - if (!comp) comp = &dummy; - if (stbi__get32be(s) != 0x38425053) { - stbi__rewind( s ); - return 0; + if (!x) + x = &dummy; + if (!y) + y = &dummy; + if (!comp) + comp = &dummy; + if (stbi__get32be(s) != 0x38425053) + { + stbi__rewind(s); + return 0; } - if (stbi__get16be(s) != 1) { - stbi__rewind( s ); - return 0; + if (stbi__get16be(s) != 1) + { + stbi__rewind(s); + return 0; } stbi__skip(s, 6); channelCount = stbi__get16be(s); - if (channelCount < 0 || channelCount > 16) { - stbi__rewind( s ); - return 0; + if (channelCount < 0 || channelCount > 16) + { + stbi__rewind(s); + return 0; } *y = stbi__get32be(s); *x = stbi__get32be(s); depth = stbi__get16be(s); - if (depth != 8 && depth != 16) { - stbi__rewind( s ); - return 0; + if (depth != 8 && depth != 16) + { + stbi__rewind(s); + return 0; } - if (stbi__get16be(s) != 3) { - stbi__rewind( s ); - return 0; + if (stbi__get16be(s) != 3) + { + stbi__rewind(s); + return 0; } *comp = 4; return 1; @@ -7394,26 +8697,30 @@ static int stbi__psd_info(stbi__context *s, int *x, int *y, int *comp) static int stbi__psd_is16(stbi__context *s) { int channelCount, depth; - if (stbi__get32be(s) != 0x38425053) { - stbi__rewind( s ); - return 0; + if (stbi__get32be(s) != 0x38425053) + { + stbi__rewind(s); + return 0; } - if (stbi__get16be(s) != 1) { - stbi__rewind( s ); - return 0; + if (stbi__get16be(s) != 1) + { + stbi__rewind(s); + return 0; } stbi__skip(s, 6); channelCount = stbi__get16be(s); - if (channelCount < 0 || channelCount > 16) { - stbi__rewind( s ); - return 0; + if (channelCount < 0 || channelCount > 16) + { + stbi__rewind(s); + return 0; } STBI_NOTUSED(stbi__get32be(s)); STBI_NOTUSED(stbi__get32be(s)); depth = stbi__get16be(s); - if (depth != 16) { - stbi__rewind( s ); - return 0; + if (depth != 16) + { + stbi__rewind(s); + return 0; } return 1; } @@ -7422,14 +8729,18 @@ static int stbi__psd_is16(stbi__context *s) #ifndef STBI_NO_PIC static int stbi__pic_info(stbi__context *s, int *x, int *y, int *comp) { - int act_comp=0,num_packets=0,chained,dummy; + int act_comp = 0, num_packets = 0, chained, dummy; stbi__pic_packet packets[10]; - if (!x) x = &dummy; - if (!y) y = &dummy; - if (!comp) comp = &dummy; + if (!x) + x = &dummy; + if (!y) + y = &dummy; + if (!comp) + comp = &dummy; - if (!stbi__pic_is4(s,"\x53\x80\xF6\x34")) { + if (!stbi__pic_is4(s, "\x53\x80\xF6\x34")) + { stbi__rewind(s); return 0; } @@ -7438,37 +8749,42 @@ static int stbi__pic_info(stbi__context *s, int *x, int *y, int *comp) *x = stbi__get16be(s); *y = stbi__get16be(s); - if (stbi__at_eof(s)) { - stbi__rewind( s); + if (stbi__at_eof(s)) + { + stbi__rewind(s); return 0; } - if ( (*x) != 0 && (1 << 28) / (*x) < (*y)) { - stbi__rewind( s ); + if ((*x) != 0 && (1 << 28) / (*x) < (*y)) + { + stbi__rewind(s); return 0; } stbi__skip(s, 8); - do { + do + { stbi__pic_packet *packet; - if (num_packets==sizeof(packets)/sizeof(packets[0])) + if (num_packets == sizeof(packets) / sizeof(packets[0])) return 0; packet = &packets[num_packets++]; chained = stbi__get8(s); - packet->size = stbi__get8(s); - packet->type = stbi__get8(s); + packet->size = stbi__get8(s); + packet->type = stbi__get8(s); packet->channel = stbi__get8(s); act_comp |= packet->channel; - if (stbi__at_eof(s)) { - stbi__rewind( s ); - return 0; + if (stbi__at_eof(s)) + { + stbi__rewind(s); + return 0; } - if (packet->size != 8) { - stbi__rewind( s ); - return 0; + if (packet->size != 8) + { + stbi__rewind(s); + return 0; } } while (chained); @@ -7491,14 +8807,15 @@ static int stbi__pic_info(stbi__context *s, int *x, int *y, int *comp) #ifndef STBI_NO_PNM -static int stbi__pnm_test(stbi__context *s) +static int stbi__pnm_test(stbi__context *s) { char p, t; - p = (char) stbi__get8(s); - t = (char) stbi__get8(s); - if (p != 'P' || (t != '5' && t != '6')) { - stbi__rewind( s ); - return 0; + p = (char)stbi__get8(s); + t = (char)stbi__get8(s); + if (p != 'P' || (t != '5' && t != '6')) + { + stbi__rewind(s); + return 0; } return 1; } @@ -7512,107 +8829,123 @@ static void *stbi__pnm_load(stbi__context *s, int *x, int *y, int *comp, int req if (ri->bits_per_channel == 0) return 0; - if (s->img_y > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large","Very large image (corrupt?)"); - if (s->img_x > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large","Very large image (corrupt?)"); + if (s->img_y > STBI_MAX_DIMENSIONS) + return stbi__errpuc("too large", "Very large image (corrupt?)"); + if (s->img_x > STBI_MAX_DIMENSIONS) + return stbi__errpuc("too large", "Very large image (corrupt?)"); *x = s->img_x; *y = s->img_y; - if (comp) *comp = s->img_n; + if (comp) + *comp = s->img_n; if (!stbi__mad4sizes_valid(s->img_n, s->img_x, s->img_y, ri->bits_per_channel / 8, 0)) return stbi__errpuc("too large", "PNM too large"); - out = (stbi_uc *) stbi__malloc_mad4(s->img_n, s->img_x, s->img_y, ri->bits_per_channel / 8, 0); - if (!out) return stbi__errpuc("outofmem", "Out of memory"); - if (!stbi__getn(s, out, s->img_n * s->img_x * s->img_y * (ri->bits_per_channel / 8))) { + out = (stbi_uc *)stbi__malloc_mad4(s->img_n, s->img_x, s->img_y, ri->bits_per_channel / 8, 0); + if (!out) + return stbi__errpuc("outofmem", "Out of memory"); + if (!stbi__getn(s, out, s->img_n * s->img_x * s->img_y * (ri->bits_per_channel / 8))) + { STBI_FREE(out); return stbi__errpuc("bad PNM", "PNM file truncated"); } - if (req_comp && req_comp != s->img_n) { - if (ri->bits_per_channel == 16) { - out = (stbi_uc *) stbi__convert_format16((stbi__uint16 *) out, s->img_n, req_comp, s->img_x, s->img_y); - } else { + if (req_comp && req_comp != s->img_n) + { + if (ri->bits_per_channel == 16) + { + out = (stbi_uc *)stbi__convert_format16((stbi__uint16 *)out, s->img_n, req_comp, s->img_x, s->img_y); + } + else + { out = stbi__convert_format(out, s->img_n, req_comp, s->img_x, s->img_y); } - if (out == NULL) return out; // stbi__convert_format frees input on failure + if (out == NULL) + return out; // stbi__convert_format frees input on failure } return out; } -static int stbi__pnm_isspace(char c) +static int stbi__pnm_isspace(char c) { return c == ' ' || c == '\t' || c == '\n' || c == '\v' || c == '\f' || c == '\r'; } -static void stbi__pnm_skip_whitespace(stbi__context *s, char *c) +static void stbi__pnm_skip_whitespace(stbi__context *s, char *c) { - for (;;) { + for (;;) + { while (!stbi__at_eof(s) && stbi__pnm_isspace(*c)) - *c = (char) stbi__get8(s); + *c = (char)stbi__get8(s); if (stbi__at_eof(s) || *c != '#') break; - while (!stbi__at_eof(s) && *c != '\n' && *c != '\r' ) - *c = (char) stbi__get8(s); + while (!stbi__at_eof(s) && *c != '\n' && *c != '\r') + *c = (char)stbi__get8(s); } } -static int stbi__pnm_isdigit(char c) +static int stbi__pnm_isdigit(char c) { return c >= '0' && c <= '9'; } -static int stbi__pnm_getinteger(stbi__context *s, char *c) +static int stbi__pnm_getinteger(stbi__context *s, char *c) { int value = 0; - while (!stbi__at_eof(s) && stbi__pnm_isdigit(*c)) { - value = value*10 + (*c - '0'); - *c = (char) stbi__get8(s); - if((value > 214748364) || (value == 214748364 && *c > '7')) - return stbi__err("integer parse overflow", "Parsing an integer in the PPM header overflowed a 32-bit int"); + while (!stbi__at_eof(s) && stbi__pnm_isdigit(*c)) + { + value = value * 10 + (*c - '0'); + *c = (char)stbi__get8(s); + if ((value > 214748364) || (value == 214748364 && *c > '7')) + return stbi__err("integer parse overflow", "Parsing an integer in the PPM header overflowed a 32-bit int"); } return value; } -static int stbi__pnm_info(stbi__context *s, int *x, int *y, int *comp) +static int stbi__pnm_info(stbi__context *s, int *x, int *y, int *comp) { int maxv, dummy; char c, p, t; - if (!x) x = &dummy; - if (!y) y = &dummy; - if (!comp) comp = &dummy; + if (!x) + x = &dummy; + if (!y) + y = &dummy; + if (!comp) + comp = &dummy; stbi__rewind(s); // Get identifier - p = (char) stbi__get8(s); - t = (char) stbi__get8(s); - if (p != 'P' || (t != '5' && t != '6')) { - stbi__rewind(s); - return 0; + p = (char)stbi__get8(s); + t = (char)stbi__get8(s); + if (p != 'P' || (t != '5' && t != '6')) + { + stbi__rewind(s); + return 0; } - *comp = (t == '6') ? 3 : 1; // '5' is 1-component .pgm; '6' is 3-component .ppm + *comp = (t == '6') ? 3 : 1; // '5' is 1-component .pgm; '6' is 3-component .ppm - c = (char) stbi__get8(s); + c = (char)stbi__get8(s); stbi__pnm_skip_whitespace(s, &c); *x = stbi__pnm_getinteger(s, &c); // read width - if(*x == 0) - return stbi__err("invalid width", "PPM image header had zero or overflowing width"); + if (*x == 0) + return stbi__err("invalid width", "PPM image header had zero or overflowing width"); stbi__pnm_skip_whitespace(s, &c); *y = stbi__pnm_getinteger(s, &c); // read height if (*y == 0) - return stbi__err("invalid width", "PPM image header had zero or overflowing width"); + return stbi__err("invalid width", "PPM image header had zero or overflowing width"); stbi__pnm_skip_whitespace(s, &c); - maxv = stbi__pnm_getinteger(s, &c); // read max value + maxv = stbi__pnm_getinteger(s, &c); // read max value if (maxv > 65535) return stbi__err("max value > 65535", "PPM image supports only 8-bit and 16-bit images"); else if (maxv > 255) @@ -7624,78 +8957,90 @@ static int stbi__pnm_info(stbi__context *s, int *x, int *y, int *comp) static int stbi__pnm_is16(stbi__context *s) { if (stbi__pnm_info(s, NULL, NULL, NULL) == 16) - return 1; + return 1; return 0; } #endif static int stbi__info_main(stbi__context *s, int *x, int *y, int *comp) { - #ifndef STBI_NO_JPEG - if (stbi__jpeg_info(s, x, y, comp)) return 1; - #endif +#ifndef STBI_NO_JPEG + if (stbi__jpeg_info(s, x, y, comp)) + return 1; +#endif - #ifndef STBI_NO_PNG - if (stbi__png_info(s, x, y, comp)) return 1; - #endif +#ifndef STBI_NO_PNG + if (stbi__png_info(s, x, y, comp)) + return 1; +#endif - #ifndef STBI_NO_GIF - if (stbi__gif_info(s, x, y, comp)) return 1; - #endif +#ifndef STBI_NO_GIF + if (stbi__gif_info(s, x, y, comp)) + return 1; +#endif - #ifndef STBI_NO_BMP - if (stbi__bmp_info(s, x, y, comp)) return 1; - #endif +#ifndef STBI_NO_BMP + if (stbi__bmp_info(s, x, y, comp)) + return 1; +#endif - #ifndef STBI_NO_PSD - if (stbi__psd_info(s, x, y, comp)) return 1; - #endif +#ifndef STBI_NO_PSD + if (stbi__psd_info(s, x, y, comp)) + return 1; +#endif - #ifndef STBI_NO_PIC - if (stbi__pic_info(s, x, y, comp)) return 1; - #endif +#ifndef STBI_NO_PIC + if (stbi__pic_info(s, x, y, comp)) + return 1; +#endif - #ifndef STBI_NO_PNM - if (stbi__pnm_info(s, x, y, comp)) return 1; - #endif +#ifndef STBI_NO_PNM + if (stbi__pnm_info(s, x, y, comp)) + return 1; +#endif - #ifndef STBI_NO_HDR - if (stbi__hdr_info(s, x, y, comp)) return 1; - #endif +#ifndef STBI_NO_HDR + if (stbi__hdr_info(s, x, y, comp)) + return 1; +#endif - // test tga last because it's a crappy test! - #ifndef STBI_NO_TGA +// test tga last because it's a crappy test! +#ifndef STBI_NO_TGA if (stbi__tga_info(s, x, y, comp)) - return 1; - #endif + return 1; +#endif return stbi__err("unknown image type", "Image not of any known type, or corrupt"); } static int stbi__is_16_main(stbi__context *s) { - #ifndef STBI_NO_PNG - if (stbi__png_is16(s)) return 1; - #endif +#ifndef STBI_NO_PNG + if (stbi__png_is16(s)) + return 1; +#endif - #ifndef STBI_NO_PSD - if (stbi__psd_is16(s)) return 1; - #endif +#ifndef STBI_NO_PSD + if (stbi__psd_is16(s)) + return 1; +#endif - #ifndef STBI_NO_PNM - if (stbi__pnm_is16(s)) return 1; - #endif +#ifndef STBI_NO_PNM + if (stbi__pnm_is16(s)) + return 1; +#endif return 0; } #ifndef STBI_NO_STDIO STBIDEF int stbi_info(char const *filename, int *x, int *y, int *comp) { - FILE *f = stbi__fopen(filename, "rb"); - int result; - if (!f) return stbi__err("can't fopen", "Unable to open file"); - result = stbi_info_from_file(f, x, y, comp); - fclose(f); - return result; + FILE *f = stbi__fopen(filename, "rb"); + int result; + if (!f) + return stbi__err("can't fopen", "Unable to open file"); + result = stbi_info_from_file(f, x, y, comp); + fclose(f); + return result; } STBIDEF int stbi_info_from_file(FILE *f, int *x, int *y, int *comp) @@ -7704,19 +9049,20 @@ STBIDEF int stbi_info_from_file(FILE *f, int *x, int *y, int *comp) stbi__context s; long pos = ftell(f); stbi__start_file(&s, f); - r = stbi__info_main(&s,x,y,comp); - fseek(f,pos,SEEK_SET); + r = stbi__info_main(&s, x, y, comp); + fseek(f, pos, SEEK_SET); return r; } STBIDEF int stbi_is_16_bit(char const *filename) { - FILE *f = stbi__fopen(filename, "rb"); - int result; - if (!f) return stbi__err("can't fopen", "Unable to open file"); - result = stbi_is_16_bit_from_file(f); - fclose(f); - return result; + FILE *f = stbi__fopen(filename, "rb"); + int result; + if (!f) + return stbi__err("can't fopen", "Unable to open file"); + result = stbi_is_16_bit_from_file(f); + fclose(f); + return result; } STBIDEF int stbi_is_16_bit_from_file(FILE *f) @@ -7726,7 +9072,7 @@ STBIDEF int stbi_is_16_bit_from_file(FILE *f) long pos = ftell(f); stbi__start_file(&s, f); r = stbi__is_16_main(&s); - fseek(f,pos,SEEK_SET); + fseek(f, pos, SEEK_SET); return r; } #endif // !STBI_NO_STDIO @@ -7734,28 +9080,28 @@ STBIDEF int stbi_is_16_bit_from_file(FILE *f) STBIDEF int stbi_info_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *comp) { stbi__context s; - stbi__start_mem(&s,buffer,len); - return stbi__info_main(&s,x,y,comp); + stbi__start_mem(&s, buffer, len); + return stbi__info_main(&s, x, y, comp); } STBIDEF int stbi_info_from_callbacks(stbi_io_callbacks const *c, void *user, int *x, int *y, int *comp) { stbi__context s; - stbi__start_callbacks(&s, (stbi_io_callbacks *) c, user); - return stbi__info_main(&s,x,y,comp); + stbi__start_callbacks(&s, (stbi_io_callbacks *)c, user); + return stbi__info_main(&s, x, y, comp); } STBIDEF int stbi_is_16_bit_from_memory(stbi_uc const *buffer, int len) { stbi__context s; - stbi__start_mem(&s,buffer,len); + stbi__start_mem(&s, buffer, len); return stbi__is_16_main(&s); } STBIDEF int stbi_is_16_bit_from_callbacks(stbi_io_callbacks const *c, void *user) { stbi__context s; - stbi__start_callbacks(&s, (stbi_io_callbacks *) c, user); + stbi__start_callbacks(&s, (stbi_io_callbacks *)c, user); return stbi__is_16_main(&s); } @@ -7944,7 +9290,6 @@ STBIDEF int stbi_is_16_bit_from_callbacks(stbi_io_callbacks const *c, void *user first released version */ - /* ------------------------------------------------------------------------------ This software is available under 2 licenses -- choose whichever you prefer. diff --git a/source/text.cpp b/source/text.cpp index 3b59a3f..06002c9 100644 --- a/source/text.cpp +++ b/source/text.cpp @@ -1,11 +1,11 @@ #include "text.h" -#include // for SDL_Rect -#include // for basic_ostream, basic_ifstream, basic_istream -#include // for cout -#include "resource.h" // for Resource -#include "sprite.h" // for Sprite -#include "texture.h" // for Texture -#include "utils.h" // for Color +#include // para SDL_Rect +#include // para basic_ostream, basic_ifstream, basic_istream +#include // para cout +#include "resource.h" // para Resource +#include "sprite.h" // para Sprite +#include "texture.h" // para Texture +#include "utils.h" // para Color // Llena una estructuta TextFile desde un fichero std::shared_ptr loadTextFile(const std::string &file_path) diff --git a/source/text.h b/source/text.h index 57e15dd..edadbd4 100644 --- a/source/text.h +++ b/source/text.h @@ -1,11 +1,11 @@ #pragma once -#include // for SDL_Renderer -#include // for Uint8 -#include // for shared_ptr, unique_ptr -#include // for string -#include "sprite.h" // for Sprite -#include "utils.h" // for Color +#include // para SDL_Renderer +#include // para Uint8 +#include // para shared_ptr, unique_ptr +#include // para string +#include "sprite.h" // para Sprite +#include "utils.h" // para Color class Texture; constexpr int TEXT_COLOR = 1; diff --git a/source/texture.cpp b/source/texture.cpp index 50b9820..fe87b50 100644 --- a/source/texture.cpp +++ b/source/texture.cpp @@ -1,17 +1,17 @@ #include "texture.h" #include "utils.h" -#include // for SDL_GetError -#include // for SDL_CreateRGBSurfaceWithFormatFrom -#include // for SEEK_END, SEEK_SET -#include // for fseek, fclose, fopen, fread, ftell, NULL -#include // for malloc, free, exit -#include // for basic_ostream, operator<<, cout, endl +#include // para SDL_GetError +#include // para SDL_CreateRGBSurfaceWithFormatFrom +#include // para SEEK_END, SEEK_SET +#include // para fseek, fclose, fopen, fread, ftell, NULL +#include // para malloc, free, exit +#include // para basic_ostream, operator<<, cout, endl #include #include -#include "gif.c" // for LoadGif, LoadPalette +#include "gif.c" // para LoadGif, LoadPalette #define STB_IMAGE_IMPLEMENTATION -#include "stb_image.h" // for stbi_failure_reason, stbi_image_free +#include "stb_image.h" // para stbi_failure_reason, stbi_image_free // Constructor Texture::Texture(SDL_Renderer *renderer, const std::string &path) diff --git a/source/texture.h b/source/texture.h index f184cd5..37bfd73 100644 --- a/source/texture.h +++ b/source/texture.h @@ -1,12 +1,12 @@ #pragma once -#include // for SDL_BlendMode -#include // for SDL_PIXELFORMAT_RGBA8888, SDL_PixelF... -#include // for SDL_Point, SDL_Rect -#include // for SDL_Renderer, SDL_FLIP_NONE, SDL_TEX... -#include // for Uint8, Uint32, Uint16 -#include // for string, basic_string -#include // for vector +#include // para SDL_BlendMode +#include // para SDL_PIXELFORMAT_RGBA8888, SDL_PixelF... +#include // para SDL_Point, SDL_Rect +#include // para SDL_Renderer, SDL_FLIP_NONE, SDL_TEX... +#include // para Uint8, Uint32, Uint16 +#include // para string, basic_string +#include // para vector #include // Definiciones de tipos diff --git a/source/tiled_bg.cpp b/source/tiled_bg.cpp index 208cb08..8707840 100644 --- a/source/tiled_bg.cpp +++ b/source/tiled_bg.cpp @@ -1,12 +1,12 @@ #include "tiled_bg.h" -#include // for SDL_PIXELFORMAT_RGBA8888 -#include // for rand -#include // for unique_ptr, make_shared, make_unique -#include // for sinf -#include "resource.h" // for Resource -#include "screen.h" // for Screen -#include "sprite.h" // for Sprite -#include "texture.h" // for Texture +#include // para SDL_PIXELFORMAT_RGBA8888 +#include // para rand +#include // para unique_ptr, make_shared, make_unique +#include // para sinf +#include "resource.h" // para Resource +#include "screen.h" // para Screen +#include "sprite.h" // para Sprite +#include "texture.h" // para Texture // Constructor TiledBG::TiledBG(SDL_Rect pos, TiledBGMode mode) diff --git a/source/tiled_bg.h b/source/tiled_bg.h index 3d170f9..39ceb4a 100644 --- a/source/tiled_bg.h +++ b/source/tiled_bg.h @@ -1,8 +1,8 @@ #pragma once -#include // for SDL_Rect -#include // for SDL_Renderer, SDL_Texture -#include // for string, basic_string +#include // para SDL_Rect +#include // para SDL_Renderer, SDL_Texture +#include // para string, basic_string // Modos de funcionamiento para el tileado de fondo enum class TiledBGMode : int diff --git a/source/title.cpp b/source/title.cpp index 0ff91fa..d7b979e 100644 --- a/source/title.cpp +++ b/source/title.cpp @@ -1,25 +1,25 @@ #include "title.h" -#include // for SDL_PollEvent, SDL_Event, SDL_KEYDOWN -#include // for SDLK_1, SDLK_2, SDLK_3 -#include // for SDL_Rect -#include // for SDL_Renderer -#include // for SDL_GetTicks -#include // for char_traits, operator+, to_string, bas... -#include // for move -#include // for vector -#include "asset.h" // for Asset -#include "global_inputs.h" // for check -#include "input.h" // for Input, InputType, INPUT_DO_NOT_ALLOW_R... -#include "jail_audio.h" // for JA_GetMusicState, JA_Music_state, JA_P... -#include "lang.h" // for getText -#include "notifier.h" // for Notifier -#include "options.h" // for options -#include "param.h" // for param -#include "resource.h" // for Resource -#include "screen.h" // for Screen -#include "section.h" // for Options, options, Name, name -#include "texture.h" // for Texture -#include "utils.h" // for Param, OptionsController, Color, Param... +#include // para SDL_PollEvent, SDL_Event, SDL_KEYDOWN +#include // para SDLK_1, SDLK_2, SDLK_3 +#include // para SDL_Rect +#include // para SDL_Renderer +#include // para SDL_GetTicks +#include // para char_traits, operator+, to_string, bas... +#include // para move +#include // para vector +#include "asset.h" // para Asset +#include "global_inputs.h" // para check +#include "input.h" // para Input, InputType, INPUT_DO_NOT_ALLOW_R... +#include "jail_audio.h" // para JA_GetMusicState, JA_Music_state, JA_P... +#include "lang.h" // para getText +#include "notifier.h" // para Notifier +#include "options.h" // para options +#include "param.h" // para param +#include "resource.h" // para Resource +#include "screen.h" // para Screen +#include "section.h" // para Options, options, Name, name +#include "texture.h" // para Texture +#include "utils.h" // para Param, OptionsController, Color, Param... struct JA_Music_t; // lines 17-17 // Constructor diff --git a/source/title.h b/source/title.h index ad80e85..36667eb 100644 --- a/source/title.h +++ b/source/title.h @@ -1,15 +1,15 @@ #pragma once -#include // for Uint32 -#include // for unique_ptr, shared_ptr -#include "define_buttons.h" // for DefineButtons -#include "fade.h" // for Fade -#include "game_logo.h" // for GameLogo -#include "sprite.h" // for Sprite -#include "text.h" // for Text -#include "tiled_bg.h" // for TiledBG +#include // para Uint32 +#include // para unique_ptr, shared_ptr +#include "define_buttons.h" // para DefineButtons +#include "fade.h" // para Fade +#include "game_logo.h" // para GameLogo +#include "sprite.h" // para Sprite +#include "text.h" // para Text +#include "tiled_bg.h" // para TiledBG class Input; // lines 17-17 -#include "section.h" // for Options, options, Name, name +#include "section.h" // para Options, options, Name, name class Screen; // lines 18-18 class Texture; // lines 20-20 namespace section diff --git a/source/utils.cpp b/source/utils.cpp index ccd8a0e..c808cb5 100644 --- a/source/utils.cpp +++ b/source/utils.cpp @@ -2,10 +2,10 @@ #include #include #include -#include // for min, clamp, find_if_not, transform -#include // for tolower, isspace -#include // for cos, pow, M_PI -#include // for operator< +#include // para min, clamp, find_if_not, transform +#include // para tolower, isspace +#include // para cos, pow, M_PI +#include // para operator< struct JA_Music_t; // lines 7-7 struct JA_Sound_t; // lines 8-8 diff --git a/source/utils.h b/source/utils.h index 46cdef9..db7d156 100644 --- a/source/utils.h +++ b/source/utils.h @@ -1,12 +1,12 @@ #pragma once -#include // for SDL_GameControllerButton -#include // for SDL_Rect, SDL_Point -#include // for SDL_Renderer -#include // for Uint8 -#include // for int32_t -#include // for string -#include // for vector +#include // para SDL_GameControllerButton +#include // para SDL_Rect, SDL_Point +#include // para SDL_Renderer +#include // para Uint8 +#include // para int32_t +#include // para string +#include // para vector enum class InputType : int; enum class ScreenFilter; // lines 14-14 enum class ScreenVideoMode; // lines 15-15 @@ -49,7 +49,7 @@ struct Circle int x, y, r; // Constructor por defecto - Circle() : x(0), y(0), r(0) {} + Circle() : x(0), y(0), r(0) {} // Constructor Circle(int xCoord, int yCoord, int radius) diff --git a/source/writer.cpp b/source/writer.cpp index 910a61d..7a1c65a 100644 --- a/source/writer.cpp +++ b/source/writer.cpp @@ -1,5 +1,5 @@ #include "writer.h" -#include "text.h" // for Text +#include "text.h" // para Text // Actualiza el objeto void Writer::update() diff --git a/source/writer.h b/source/writer.h index e78bac0..7b9e510 100644 --- a/source/writer.h +++ b/source/writer.h @@ -1,7 +1,7 @@ #pragma once -#include // for shared_ptr -#include // for string +#include // para shared_ptr +#include // para string class Text; // Clase Writer. Pinta texto en pantalla letra a letra a partir de una cadena y un objeto Text