diff --git a/SDL#2/SDL#1/Sprite.cpp b/SDL#2/SDL#1/Sprite.cpp deleted file mode 100644 index beeefb7..0000000 --- a/SDL#2/SDL#1/Sprite.cpp +++ /dev/null @@ -1,132 +0,0 @@ - -/* [CONSTRUCTOR] Construction de la surface vide -=========================================================*/ -Sprite::Sprite(SDL_Rect r){ - _surface = SDL_CreateRGBSurface(0, r.w, r.h, 32, 0, 0, 0, 0); - - // On definit les dimensions - _rect = (SDL_Rect){r.x, r.y, r.w, r.h}; - _origin = (SDL_Rect){0, 0, r.w, r.h}; - - // On applique les offset - SDL_SetClipRect( _surface, &_rect ); - -} - - - -/* [CONSTRUCTOR] Construction de la surface avec couleur -=========================================================*/ -Sprite::Sprite(const int rgb[], SDL_Rect r){ - cout << "a: [" << (sizeof(rgb)/sizeof(*rgb)) << "]" << endl; - - _surface = SDL_CreateRGBSurface(0, r.w, r.h, 32, 0, 0, 0, rgb[3]); - - // On recupere la couleur - Uint32 color = SDL_MapRGBA( _surface->format, rgb[0], rgb[1], rgb[2], rgb[3]); - - // On remplit avec la couleur - SDL_FillRect( _surface, NULL, color ); - - // On definit les dimensions - _rect = (SDL_Rect){r.x, r.y, r.w, r.h}; - _origin = (SDL_Rect){0, 0, r.w, r.h}; - - - // On applique les offset - SDL_SetClipRect( _surface, &_rect ); -} - - - -/* [CONSTRUCTOR] Construction de la surface avec image -=========================================================*/ -Sprite::Sprite(const char url[], SDL_Rect r, SDL_Rect clip){ - - /* (1) On cree la surface (avec image) */ - _surface = IMG_Load( url ); - - // Gestion erreur - if( _surface == NULL ) - return; - - // On definit les dimensions - _rect = (SDL_Rect){r.x, r.y, r.w, r.h}; - _origin = (SDL_Rect){clip.x, clip.y, r.w, r.h}; - - // On applique le clip - SDL_SetClipRect( _surface, &clip ); - -} - - - -/* [APPENDTO] Ajoute le Sprite a une autre -=========================================================*/ -void Sprite::appendTo(SDL_Surface *dest){ - SDL_BlitSurface( _surface, &_origin, dest, &_rect ); -} - -/* [SURFACE] Retourne la surface -=========================================================*/ -SDL_Surface *Sprite::surface(){ return _surface; } - - - - - - - - - - - - - - - - -/**********************************/ -/*********** SPRITEGROUP **********/ -/**********************************/ -/* [CONSTRUCTOR] Initialisation de la liste de Sprite -=========================================================*/ -SpriteGroup::SpriteGroup(){ - // _sprites = new vector(0); -} - -/* [ADD] Ajoute un Sprite au groupe -=========================================================*/ -void SpriteGroup::add(Sprite *s){ - _sprites.push_back( s ); -} - -/* [REMOVE] Suppression d'un Sprite du groupe -=========================================================*/ -void SpriteGroup::remove(Sprite *s){ - int index = -1; // on cherche l'indice du sprite - - // On parcours la liste pour trouver l'indice - for( int i = 0 ; i < _sprites.size() ; i++ ) - if( _sprites[i] == s ) index = i; - - // Si on a pas trouve l'indice - if( index == -1 ) return; - - // On supprime le sprite de la liste - _sprites.erase(_sprites.begin() + index ); - -} - -/* [APPEBDTI] Ajoute tous les Sprite du groupe a une surface parente -=========================================================*/ -void SpriteGroup::appendTo(SDL_Surface *dest){ - for( int i = 0 ; i < _sprites.size() ; i++ ) - _sprites[i]->appendTo( dest ); -} - -/* [GET] Retourne le Sprite d'index donne -=========================================================*/ -Sprite* SpriteGroup::get(int i){ - return _sprites[i]; -} \ No newline at end of file diff --git a/SDL#2/SDL#1/Sprite.h b/SDL#2/SDL#1/Sprite.h deleted file mode 100644 index eb2ba82..0000000 --- a/SDL#2/SDL#1/Sprite.h +++ /dev/null @@ -1,64 +0,0 @@ -#ifndef DEF_SPRITE_H - - #define DEF_SPRITE_H - - /* [LIBS] Internes - =========================================================*/ - #include "SDL.h" - #include "SDL_image.h" - #include - - /* [LIBS] Externes - =========================================================*/ - - - /* [NS] Namespaces - =========================================================*/ - using namespace std; - - - class Sprite{ - - public: - Sprite(SDL_Rect r); - Sprite(const int rgb[], SDL_Rect r); - Sprite(const char url[], SDL_Rect r, SDL_Rect clip); - - void setImage(const char url[], int ox=0, int oy=0); - - // ~Sprite(); - void appendTo(SDL_Surface *dest); - - // GETTERS - SDL_Surface *surface(); - - private: - SDL_Surface *_surface; - SDL_Rect _rect; - SDL_Rect _origin; - - }; - - /* [AGGR] Groupement de Sprite - =========================================================*/ - class SpriteGroup{ - - public: - SpriteGroup(); - void add(Sprite *s); - void remove(Sprite *s); - Sprite* get(int i); - void appendTo(SDL_Surface *dest); - - private: - vector _sprites; - - }; - - - /* [BODY] Inclusion du corps - =========================================================*/ - #include "Sprite.cpp" - - -#endif \ No newline at end of file diff --git a/SDL#2/SDL#1/exe b/SDL#2/SDL#1/exe deleted file mode 100755 index ab1c0eb..0000000 Binary files a/SDL#2/SDL#1/exe and /dev/null differ diff --git a/SDL#2/SDL#1/main.cpp b/SDL#2/SDL#1/main.cpp deleted file mode 100644 index 38a022f..0000000 --- a/SDL#2/SDL#1/main.cpp +++ /dev/null @@ -1,93 +0,0 @@ -#include "main.h" - -// On cree un sdl-toplevel statique -static sdltl *mgr = NULL; -static bool running = true; - - - -int main(int argc, char* argv[]) { - srand(time(0)); - - /* [0] Initialisation de SDL - =========================================================*/ - mgr = new sdltl("Ma fenetre SDL", WIN_WIDTH, WIN_HEIGHT); - - /* [1] Creation de la fenetre - =========================================================*/ - if( !mgr->status() ) cout << "Erreur: " << SDL_GetError() << endl; - - - /* [3] On definit le background color - =========================================================*/ - mgr->setBackground(255, 255, 255); - // bool imageLoaded = mgr->setImage( "src/1.bmp" ); - - - - /* [4] On ajoute une sprite - =========================================================*/ - SpriteGroup background; - - /* (1) Bloc vide */ - background.add( new Sprite( - (SDL_Rect) {0, 0, 200, 200} - )); - - /* (2) Bloc rose */ - int pink[] = {255, 0, 255}; - cout << "a: [" << (sizeof(pink)/sizeof(*pink)) << "]" << endl; - - background.add( new Sprite( - pink, - (SDL_Rect){200, 0, 200, 200} - )); - - /* (2) Bloc image */ - background.add( new Sprite( - "src/1.bmp", - (SDL_Rect){400, 0, 200, 200}, - (SDL_Rect){200, 200, 200, 200} - )); - - - - - /* [5] On ajoute les elements + mise a jour affichage - =========================================================*/ - background.appendTo( mgr->screen() ); - mgr->update(); - - - - - - /* [n-1] Boucle infinie - =========================================================*/ - mgr->manageFps(FPS); - running = true; - while(running){ - - mgr->waitEvent(SDL_QUIT, &quitEventHandler); - - // Gestion des FPS (vitesse de la boucle) - mgr->manageFps(); - } - - - - - - - - /* [n] Fin d'execution - =========================================================*/ - delete mgr; - return 0; -} - - -void quitEventHandler(SDL_Event *e){ - cout << "Ferme" << endl; - running = false; -} \ No newline at end of file diff --git a/SDL#2/SDL#1/main.h b/SDL#2/SDL#1/main.h deleted file mode 100644 index 26ca25d..0000000 --- a/SDL#2/SDL#1/main.h +++ /dev/null @@ -1,30 +0,0 @@ -#ifndef DEF_MAIN_H - - #define DEF_MAIN_H - - /* [LIB] Internes - =========================================================*/ - #include - #include - - /* [LIB] Externes - =========================================================*/ - #include "sdltl.h" // gestion de la fenetre et SDL - #include "Sprite.h" // gestion des sprites - - /* [NS] Namespace - =========================================================*/ - using namespace std; - - /* [CONST] Constantes et enumerations - =========================================================*/ - #define WIN_WIDTH 600 - #define WIN_HEIGHT 400 - - #define FPS 60 - - /* [FONCTIONS] Fonctions du corps - =========================================================*/ - void quitEventHandler(SDL_Event *e); - -#endif \ No newline at end of file diff --git a/SDL#2/SDL#1/main.o b/SDL#2/SDL#1/main.o deleted file mode 100644 index b6323b3..0000000 Binary files a/SDL#2/SDL#1/main.o and /dev/null differ diff --git a/SDL#2/SDL#1/makefile b/SDL#2/SDL#1/makefile deleted file mode 100644 index 656d573..0000000 --- a/SDL#2/SDL#1/makefile +++ /dev/null @@ -1,41 +0,0 @@ -.PHONY: init, clean, mrproper -CC=g++ -FLAGS=`pkg-config sdl2 --cflags --libs` -l SDL2_image - -# INIT > STRUCTURE DE FICHIERS POUR LES EXECUTABLES -init: clean - mkdir dep.o - - - - - - - - - - -# EXECUTABLE > DEPENDANCES DE L'EXECUTABLE -all: init main.o clean - rm -r dep.o - $(CC) main.o -o exe $(FLAGS) - -# AMORCE > PROGRAMME PRINCIPAL -main.o: main.cpp - $(CC) -c $< -o main.o $(FLAGS) - - - - - - - - -# RESET > SUPPRESSION DES FICHIERS -clean: - touch init.o - rm -r *.o - -# RESET FOR REBUILD > SUPPRESSION DE L'EXECUTABLE -mrproper: - rm exe diff --git a/SDL#2/SDL#1/sdltl.cpp b/SDL#2/SDL#1/sdltl.cpp deleted file mode 100644 index b823c03..0000000 --- a/SDL#2/SDL#1/sdltl.cpp +++ /dev/null @@ -1,134 +0,0 @@ -/* [CONSTRUCTOR] Constructeur de la classe -=========================================================*/ -sdltl::sdltl(const char *t, int w, int h){ - // default values - _lasttick = 0; - _fpstime = 1000/60; - - SDL_Init( SDL_INIT_EVERYTHING ); - - _window = NULL; - _screen = NULL; - - // Creation de la fenetre - _window = SDL_CreateWindow( - t, - SDL_WINDOWPOS_CENTERED, - SDL_WINDOWPOS_CENTERED, - w, - h, - SDL_WINDOW_SHOWN - ); - - // Gestion erreur - if( _window == NULL ) - _status = false; - - // On recupere la surface - _screen = SDL_GetWindowSurface( _window ); - - // On retourne que tout s'est bien passe - _status = true; -} - -/* [DESTROYER] Destructeur de la classe -=========================================================*/ -sdltl::~sdltl(){ - SDL_DestroyWindow( _window ); - SDL_Quit(); -} - -/* [STATUS] Retourne le status -=========================================================*/ -bool sdltl::status(){ - return _window != NULL && _screen != NULL; -} - - -/* [WINDOW] Retourne la fenetre -=========================================================*/ -SDL_Window* sdltl::window(){ return _window; } - - -/* [SCREEN] Retourne la fenetre -=========================================================*/ -SDL_Surface* sdltl::screen(){ return _screen; } - - -/* [SETBACKGROUND] Modifie la couleur de fond -=========================================================*/ -void sdltl::setBackground(int r, int g, int b){ - Uint32 color = SDL_MapRGB( _screen->format, r, g, b ); - - SDL_FillRect( _screen, NULL, color ); -} - -/* [SETIMAGE] Met une image en fond -=========================================================*/ -bool sdltl::setImage(const char *url){ - SDL_Surface *image = NULL; - image = SDL_LoadBMP( url ); - - // Si erreur de chargement image - if( image == NULL ) - return false; - - SDL_Rect dimensions; - dimensions.x = 0; - dimensions.y = 0; - SDL_GetWindowSize(_window, &dimensions.w, &dimensions.h); - - SDL_BlitSurface( image, NULL, _screen, &dimensions); - - // On libere la surface pour l'image - SDL_FreeSurface(image); - image = NULL; - - return true; -} - -/* [UPDATE] Mise a jour du rendu -=========================================================*/ -void sdltl::update(){ - SDL_UpdateWindowSurface( _window ); -} - -/* [WAITEVENT] Attends un evenement pour executer -=========================================================*/ -void sdltl::waitEvent(SDL_EventType t, void(*handler)(SDL_Event*)){ - SDL_Event event; - - // On attends un evenement - while( SDL_PollEvent(&event) ){ - - // quand evenement, si type = t - if( event.type == t ) - (*handler)(&event); - - } -} - -/* [MANAGEFTP] Gestion de la vitesse de boucle -=========================================================*/ -void sdltl::manageFps(const int fps){ - /* (1) Definition de fps */ - if( fps != 0 ) _fpstime = 1000/fps; - - /* (2) Initialisation timer */ - if( _lasttick == 0 ) - _lasttick = SDL_GetTicks(); - - /* (3) Utilisation en fin de WHILE() */ - - // 1 > Si trop rapide, on attends + definit _lasttick - else if( SDL_GetTicks()-_lasttick < _fpstime ){ - SDL_Delay( _fpstime - (SDL_GetTicks()-_lasttick) ); - - _lasttick = SDL_GetTicks() + _fpstime - (SDL_GetTicks()-_lasttick); - - // 2 > Temps ok - }else - _lasttick = SDL_GetTicks(); - - -} \ No newline at end of file diff --git a/SDL#2/SDL#1/sdltl.h b/SDL#2/SDL#1/sdltl.h deleted file mode 100644 index b59d926..0000000 --- a/SDL#2/SDL#1/sdltl.h +++ /dev/null @@ -1,53 +0,0 @@ -#ifndef DEF_SDLTL_H - - #define DEF_SDLTL_H - - /* [LIBS] Internes - =========================================================*/ - #include "SDL.h" - - /* [LIBS] Externes - =========================================================*/ - - - /* [NS] Namespaces - =========================================================*/ - using namespace std; - - - class sdltl{ - - public: - sdltl(const char *t, int w, int h); - ~sdltl(); - SDL_Window *window(); - SDL_Surface *screen(); - bool status(); - void setBackground(int r, int g, int b); - bool setImage(const char *url); - void waitEvent(SDL_EventType t, void(*handler)(SDL_Event*) ); - void update(); - - void manageFps(const int fps=0); - - private: - // gestion FPS - Uint32 _lasttick; - Uint32 _fpstime; - - // status de l'initialisation - bool _status; - - // Elements utiles - SDL_Window *_window; - SDL_Surface *_screen; - - }; - - - /* [BODY] Inclusion du corps - =========================================================*/ - #include "sdltl.cpp" - - -#endif \ No newline at end of file diff --git a/SDL#2/SDL#1/src/01.jpg b/SDL#2/SDL#1/src/01.jpg deleted file mode 100644 index a286e6c..0000000 Binary files a/SDL#2/SDL#1/src/01.jpg and /dev/null differ diff --git a/SDL#2/SDL#1/src/1.bmp b/SDL#2/SDL#1/src/1.bmp deleted file mode 100644 index 5641e75..0000000 Binary files a/SDL#2/SDL#1/src/1.bmp and /dev/null differ diff --git a/SDL#2/Sprite.cpp b/SDL#2/Sprite.cpp index ff9dd56..92e8559 100644 --- a/SDL#2/Sprite.cpp +++ b/SDL#2/Sprite.cpp @@ -1,11 +1,12 @@ /* [CONSTRUCTOR] Construction de la surface vide =========================================================*/ -Sprite::Sprite(int x, int y, int w, int h){ - _surface = SDL_CreateRGBSurface(0, w, h, 32, 0, 0, 0, 0); +Sprite::Sprite(SDL_Rect r){ + _surface = SDL_CreateRGBSurface(0, r.w, r.h, 32, 0, 0, 0, 0); // On definit les dimensions - _rect = (SDL_Rect){x, y, w, h}; + _rect = (SDL_Rect){r.x, r.y, r.w, r.h}; + _origin = (SDL_Rect){0, 0, r.w, r.h}; // On applique les offset SDL_SetClipRect( _surface, &_rect ); @@ -16,18 +17,22 @@ Sprite::Sprite(int x, int y, int w, int h){ /* [CONSTRUCTOR] Construction de la surface avec couleur =========================================================*/ -Sprite::Sprite(int c[], int x, int y, int w, int h){ - _surface = SDL_CreateRGBSurface(0, w, h, 32, 0, 0, 0, 0); +Sprite::Sprite(const int rgb[], SDL_Rect r){ + cout << "a: [" << (sizeof(rgb)/sizeof(*rgb)) << "]" << endl; + + _surface = SDL_CreateRGBSurface(0, r.w, r.h, 32, 0, 0, 0, rgb[3]); // On recupere la couleur - Uint32 color = SDL_MapRGB( _surface->format, c[0], c[1], c[2]); + Uint32 color = SDL_MapRGBA( _surface->format, rgb[0], rgb[1], rgb[2], rgb[3]); // On remplit avec la couleur SDL_FillRect( _surface, NULL, color ); // On definit les dimensions - _rect = (SDL_Rect){x, y, w, h}; + _rect = (SDL_Rect){r.x, r.y, r.w, r.h}; + _origin = (SDL_Rect){0, 0, r.w, r.h}; + // On applique les offset SDL_SetClipRect( _surface, &_rect ); } @@ -36,9 +41,9 @@ Sprite::Sprite(int c[], int x, int y, int w, int h){ /* [CONSTRUCTOR] Construction de la surface avec image =========================================================*/ -Sprite::Sprite(const char url[], int x, int y, int w, int h){ +Sprite::Sprite(const char url[], SDL_Rect r, SDL_Rect clip){ + /* (1) On cree la surface (avec image) */ - // _surface = SDL_LoadBMP( url ); _surface = IMG_Load( url ); // Gestion erreur @@ -46,10 +51,11 @@ Sprite::Sprite(const char url[], int x, int y, int w, int h){ return; // On definit les dimensions - _rect = (SDL_Rect){x, y, w, h}; + _rect = (SDL_Rect){r.x, r.y, r.w, r.h}; + _origin = (SDL_Rect){clip.x, clip.y, r.w, r.h}; - // On applique les offset - SDL_SetClipRect( _surface, &_rect ); + // On applique le clip + SDL_SetClipRect( _surface, &clip ); } @@ -58,7 +64,7 @@ Sprite::Sprite(const char url[], int x, int y, int w, int h){ /* [APPENDTO] Ajoute le Sprite a une autre =========================================================*/ void Sprite::appendTo(SDL_Surface *dest){ - SDL_BlitSurface( _surface, NULL, dest, &_rect ); + SDL_BlitSurface( _surface, &_origin, dest, &_rect ); } /* [SURFACE] Retourne la surface @@ -123,4 +129,45 @@ void SpriteGroup::appendTo(SDL_Surface *dest){ =========================================================*/ Sprite* SpriteGroup::get(int i){ return _sprites[i]; -} \ No newline at end of file +} + + + + +/* [TRHEAD] Process de l'animation +=========================================================*/ +void SpriteGroupAnimation(SDL_Window *win, SpriteGroup *sg, int t){ + int length = sg->_sprites.size(); + int timer = 0; + + /* (1) Pour chaque sprite */ + for( int i = 0 ; i < length ; i++ ){ + timer = SDL_GetTicks(); + + // On ajoute le sprite + sg->_sprites[i]->appendTo( SDL_GetWindowSurface(win) ); + + // On met a jour le rendu + SDL_UpdateWindowSurface( win ); + + if( SDL_GetTicks()-timer < t ) + SDL_Delay( t - (SDL_GetTicks()-timer) ); + } + + + /* (n) On termine le thread */ + return; +} + + + + +/* [ANIMATE] Modifie le Sprite dans l'ordre du SpriteGroup +=========================================================*/ +thread* SpriteGroup::animate(SDL_Window *win, int t){ + _animation = new thread(SpriteGroupAnimation, win, this, t); + + return _animation; +} + + diff --git a/SDL#2/Sprite.h b/SDL#2/Sprite.h index 4fa6f30..2a05f08 100644 --- a/SDL#2/Sprite.h +++ b/SDL#2/Sprite.h @@ -7,6 +7,7 @@ #include "SDL.h" #include "SDL_image.h" #include + #include /* [LIBS] Externes =========================================================*/ @@ -20,9 +21,11 @@ class Sprite{ public: - Sprite(int x, int y, int w, int h); - Sprite(int c[], int x, int y, int w, int h); - Sprite(const char url[], int x, int y, int w, int h); + Sprite(SDL_Rect r); + Sprite(const int rgb[], SDL_Rect r); + Sprite(const char url[], SDL_Rect r, SDL_Rect clip); + + void setImage(const char url[], int ox=0, int oy=0); // ~Sprite(); void appendTo(SDL_Surface *dest); @@ -33,6 +36,7 @@ private: SDL_Surface *_surface; SDL_Rect _rect; + SDL_Rect _origin; }; @@ -47,8 +51,14 @@ Sprite* get(int i); void appendTo(SDL_Surface *dest); + thread *animate(SDL_Window *win, int t); + private: vector _sprites; + thread *_animation; + + + friend void SpriteGroupAnimation(SDL_Window *win, SpriteGroup *sg, int t); }; diff --git a/SDL#2/exe b/SDL#2/exe index 40da867..6444a90 100755 Binary files a/SDL#2/exe and b/SDL#2/exe differ diff --git a/SDL#2/main.cpp b/SDL#2/main.cpp index 62fb6fc..b18c505 100644 --- a/SDL#2/main.cpp +++ b/SDL#2/main.cpp @@ -27,26 +27,31 @@ int main(int argc, char* argv[]) { /* [4] On ajoute une sprite =========================================================*/ - SpriteGroup back; + SpriteGroup animated_coin; - /* (1) Bloc vide */ - back.add( new Sprite( 0, 0, 200, 200 ) ); + /* (1) On enregistre les frames de l'animation */ + for( int i = 0 ; i < 7 ; i++ ){ - /* (2) Bloc rose */ - int pink[] = {255, 0, 255}; - back.add( new Sprite(pink, 200, 0, 200, 200 ) ); + animated_coin.add( new Sprite( + "src/coins.jpg", + (SDL_Rect){0, 0, 180, 180}, + (SDL_Rect){57+168*i, 40, 180, 180} + ) ); - /* (2) Bloc image */ - back.add( new Sprite("src/1.bmp", 400, 0, 200, 200 ) ); + } - /* [5] On ajoute les elements + mise a jour affichage + + + + + /* [5] On lance l'animation en parallele =========================================================*/ - back.appendTo( mgr->screen() ); - mgr->update(); - + thread* anim = animated_coin.animate(mgr->window(), 1000 ); + anim->detach(); // On laisse le thread tourner + delete anim; // On le supprime ensuite @@ -56,9 +61,10 @@ int main(int argc, char* argv[]) { mgr->manageFps(FPS); running = true; while(running){ - mgr->waitEvent(SDL_QUIT, &quitEventHandler); + cout << "Main loop" << endl; + // Gestion des FPS (vitesse de la boucle) mgr->manageFps(); } diff --git a/SDL#2/main.h b/SDL#2/main.h index 26ca25d..4e050b9 100644 --- a/SDL#2/main.h +++ b/SDL#2/main.h @@ -6,6 +6,7 @@ =========================================================*/ #include #include + #include /* [LIB] Externes =========================================================*/ diff --git a/SDL#2/main.o b/SDL#2/main.o index 91107d1..419499c 100644 Binary files a/SDL#2/main.o and b/SDL#2/main.o differ diff --git a/SDL#2/makefile b/SDL#2/makefile index 656d573..18fbdeb 100644 --- a/SDL#2/makefile +++ b/SDL#2/makefile @@ -1,6 +1,6 @@ .PHONY: init, clean, mrproper CC=g++ -FLAGS=`pkg-config sdl2 --cflags --libs` -l SDL2_image +FLAGS=-pthread -std=c++11 `pkg-config sdl2 --cflags --libs` -l SDL2_image # INIT > STRUCTURE DE FICHIERS POUR LES EXECUTABLES init: clean diff --git a/SDL#2/src/coins.jpg b/SDL#2/src/coins.jpg new file mode 100644 index 0000000..db7b8fa Binary files /dev/null and b/SDL#2/src/coins.jpg differ