Friday, October 31, 2014

Loading ".gif" animation in android (a painless guide)

Today at eveing my friend asked me if I could manage to create a custom loading dialog with a gif in android.

He told me to use a .gif file and not use sprites (frames in xml). I searched online and found out that ImageView doesn't show animation. I thought of using Hipmob/gifanimateddrawable but it was not what my friend wanted.

So, I started from scratch and made my own view class.

public class GIFView extends View {
 private Movie movie;        //class that loads the animation
 private int gifID;         //stores the id of the drawable gif file
 private long movieStart;       //the time of start of movie
 private float x, y;         //stores the x and y position of the view from the parent layout

 public int getGifID() {
  return gifID;
 }

 public void setGifID(int gifID) {
  this.gifID = gifID;
 }

 public GIFView(Context context) {
  super(context);
 }

 public GIFView(Context context, AttributeSet attrs) {
  super(context, attrs);
  //initialize the view and the above variables from the attributes
  initializeView(context, attrs); 
 }


This class extends View class. And to load gif from drawable folder we will need an integer. I've used getter/setter for the gifID and the integers x and y will be explained in a moment. There isn't much about Movie class on developers.android.com. But by searching online I found a way to use that class.

private void initializeView(Context context, AttributeSet attrs) {                                    
        
        //the name of the stylable as defined in the attrs.xml
        TypedArray a = context.obtainStyledAttributes(attrs,
                R.styleable.GIFView, 0, 0);
        
        //extract the src string
        String gifSource = a.getString(R.styleable.GIFView_src);
        String sourceName = Uri.parse(gifSource).getLastPathSegment()
                .replace(".gif", "");
        gifID = getResources().getIdentifier(sourceName, "drawable",
                getContext().getPackageName());
        a.recycle();
        
        //setting the x and y co-ordinate of the view
        x = getX();
        y = getY();
        if (gifID != 0) {
            InputStream is = getContext().getResources().openRawResource(gifID);
            movie = Movie.decodeStream(is);
            movieStart = 0;                                                    
        }
    }

The initializeView method initializes the gifID and the movie variable. Here we get the x and y co-ordinate of the view from the layout for future use. Now we will override the onDraw() method of the view class

    @Override
    protected void onDraw(Canvas canvas) {
        canvas.drawColor(Color.TRANSPARENT);
        setLayerType(View.LAYER_TYPE_SOFTWARE, null);
        super.onDraw(canvas);
        long now = android.os.SystemClock.uptimeMillis();

        if (movieStart == 0) {
            movieStart = now;
        }
        if (movie != null) {
            int relTime = (int) ((now - movieStart) % movie.duration());
            movie.setTime(relTime);
            movie.draw(canvas, x, y);
            this.invalidate();
        }
    }

Here we set canvas draw color to transparent, get the current time and then load the movie into the view. After that we invalidate so onDraw() method get called every time a new frame is to be loaded and that way we show the animation.

You can download the project from github.com

Tuesday, September 23, 2014

Dynamic Stack using struct in C

Here's a simple implementation of dynamic stack in c.

/*
 * ----------------------------------------------------------------------------
 * "THE BURGER-WARE LICENSE" (Revision 42):
 *  wrote this file. As long as you retain this notice you
 * can do whatever you want with this stuff. If we meet some day, and you think
 * this stuff is worth it, you can buy me a burger in return. Abhishek Baddi
 * ----------------------------------------------------------------------------
 */

#include<stdio.h>
#include<stdlib.h>

struct stack {
    int *data;                          //the data will be saved via this pointer
    int size;                           //this is the size of the stack
    int cursor;                         //the current position of cursor
};

void init(struct stack *x, int s) {               //initialize a stack "x" of size "s"
    x->data = (int *) malloc(s*sizeof(int)+1);    //allocate space for "s" integers on the stack
    x->size = s;                                  //remember the size
    x->cursor = 0;                                //initialize the cursor to 0
}


void push(struct stack *x, int item) {                       //push an "item" onto the stack
    if(x->cursor<x->size) {                                  //check if cursor hasn't reached the end
        x->data[x->cursor++] = item;                         //if so, copy "item" and then increment cursor
    }
    else {                                                   //cursor is at the end
        printf("[Error: %d] Stack is full.\n", x->cursor);   //print the error
    }
    //printf("cursor = %d.\n", x->cursor);
}

int pop(struct stack *x) {                           //pop an "item" from the stack
    if(x->cursor>0) {                                //if cursor is not at the base
        x->cursor--;                                 //decrement the cursor first
        //printf("cursor = %d.\n", x->cursor);
        return x->data[x->cursor];                   //then return the "item"
                                                     //we don't bother to clear the memory here.
    }
    else {
        printf("[Error: %d] Stack is empty.\n", x->cursor);        //same as before
        //printf("cursor = %d.\n", x->cursor);
        return 0;                                                  //print the error and return 0;
    }
}

int del(struct stack *x) {                      //"del" frees up the memory allocated by malloc()
    free(x->data);                              //free() requires the pointer to the allocated memory
    printf("--------------\nFreed\n--------------\n");
}

int main() {
    struct stack stk;
    int i, j;
    init(&stk, 5);                              //we initialize a stack of 5 elements

    for(i=0; i<10; ++i) {                       //we push more elements than the stack can handle
        push(&stk, i);
        printf("Pushing %d onto the stack.\n", i);
        /*
        for(j=0;j<5;++j) {
            printf("stk.data[%d]=%d\n",j,stk.data[j]);      //printing the contents of the stack after every push
        }
        */
    }
    printf("--------------\nPushing over.\n--------------\n");

    for(i=0; i<10; ++i) {
        printf("Pop %dth element: %d\n", i, pop(&stk));
    }
    del(&stk);
    return 0;
}

Every line of the code is commented. So, it'll be easier to understand.

Saturday, July 5, 2014

Star Wars in ASCII

Almost everyone has watched Star Wars on television, computer or in a theater. But have you watched an ASCII version of Star Wars?

There is a complete copy of Star Wars done entirely in ASCII characters that you can watch in your terminal (command prompt) using telnet!

Here's how:
  1. Open the terminal ('cmd.exe' for windows).
  2. Type "telnet towel.blinkenlights.nl" and press Enter.



Now, did you enjoy watching this new version of Star Wars? Well, I did and know it for sure that you would have too.

Saturday, March 22, 2014

Java Jokes

(Knock! Knock!)
Who's there?
(a very long pause..)
Java
------------------------------------------------------------
C: I'll tell you a joke.
Java: Ok.
C:(points to NULL) Look.
Java:(Frowns) I don't get it.
------------------------------------------------------------
Here's a program my friend came up with, when I asked him to find the average of 5 numbers using any loop.

public class Average {
    
    public static void main() {
        int a[] = new int[5];
        a[0] = 73;
        a[1] = 42;
        a[2] = 15;
        a[3] = 9;
        a[4] = 1;

        int b=0;
        int sum=0;
        int x=0;
        
        for( x = 0 ; x<5 ; x++ ) {
            sum = a[0] + a[1] + a[2] + a[3] + a[4];
        }
        b = sum / 5;
        System.out.println("The average is: " + b);
    }
}

Hope you enjoyed them!

Wednesday, March 5, 2014

Frame creation

Formation of frames

The following code creates frames of size "n". The frame starts with a symbol and ends with a symbol. These frames are useful for transmitting information. Simple implementation is shown below:

Suppose the input is "Abhishek Baddi" . Let's take the start symbol to be '$' and stop symbol to be '@'. The frames would be:

$Abhi@
$shek@
$ Bad@
$di  @
The code is shown below:
/*
 * ----------------------------------------------------------------------------
 * "THE BURGER-WARE LICENSE" (Revision 42):
 * <abybaddi009@gmail.com> wrote this file. As long as you retain this notice you
 * can do whatever you want with this stuff. If we meet some day, and you think
 * this stuff is worth it, you can buy me a burger in return. Abhishek Baddi
 * ----------------------------------------------------------------------------
 */
 
#include<stdio.h>
#include<string.h>

int main() {
    char a[20],STARTSYMBOL='$',STOPSYMBOL='@';
    int i,j,lenOfa;
    int FRAMESIZE=4;
    printf("Enter a string: ");
    gets(a);
    lenOfa=strlen(a);
    i=0;
    while(i<lenOfa) {
        printf("%c",STARTSYMBOL);
        for(j=0;j<FRAMESIZE;++j) {
            printf("%c",i<lenOfa?a[i]:' ');
            i++;
        }
        printf("%c\n",STOPSYMBOL);
    }
    return 0;
}

The output is shown below:

Tuesday, February 25, 2014

C++ Code to find prefix codes


Codes and the Prefix Property

Any code used for transmitting information must possess what is called the prefix property.
If a code has the prefix property, it means that no word in the code is a prefix of any other word in the code: in other words, that no longer code words begin with the identical digits making up any of the shorter code words.
As an example, let's consider a code made of code words of varying length. If 0 is a valid code word, then no other code word can start with 0 if we wish to preserve the prefix property. If 10 is a valid code word, then no other code word can start with 10.
Therefore, a valid five-word "prefix code" containing these two code words might look like one of these codes:
Event A B C D E
Code 1 0 10 110 1110 1111
Code 2 1 00 011 0100 0101

The following codes, on the other hand, would be invalid because the prefix property does not hold:

Event A B C D E
Code 3 1 00 01 001 011
Code 4 0 10 01 011 100
 
(In code 3, the code for B is a prefix of the code for D; the code for C is a prefix of the code for E. In code 4, the code for A is a prefix of the codes for C and D; the code for C is a prefix of the code for D).

The code below finds whether a given set of codes have prefix property or not.

/*
 * ----------------------------------------------------------------------------
 * "THE BURGER-WARE LICENSE" (Revision 42):
 * <abybaddi009@gmail.com> wrote this file. As long as you retain this notice you
 * can do whatever you want with this stuff. If we meet some day, and you think
 * this stuff is worth it, you can buy me a burger in return. Abhishek Baddi
 * ----------------------------------------------------------------------------
 */

#include<iostream>
#include<cstring>

using namespace std;

void strcpy2(char *d, string s);
bool mystrncmp(char const* s1, char const* s2, int n);

int main() {

    cout << "Usage:\nEnter (upto 10 binary numbers): 0 10 110 1110 1111\nOutput: The given code is a prefix code.\n\nEnter (upto 10 binary numbers): 1 00 011 0100 0101\nOutput: The given code isn't a prefix code.\n\n";

    string str1;
    char *num[10];
    for(int i=0;i<10;++i)
        num[i]=new char[10];
    cout << "Enter (upto 10 binary numbers): ";
    getline(cin,str1);


    int len=str1.size();
    char s[len];

    strcpy2(s,str1);
    char *pch = strtok (s," ");

    int i=0;

    while (pch != NULL) {
        strcpy(num[i],pch);
        pch = strtok (NULL, " ");
        i++;
    }
    len = i;
    int f=0,j;
    bool flag = true;
    for(i=0;i<len;++i) {
        f=strlen(num[i]);
        for(j=i+1;j<len;++j) {
            if(mystrncmp(num[i],num[j],f)) {
                flag=false;
            }
        }
    }

    if(flag)
        cout << "The given code is a prefix code.\n\n";
    else
        cout << "The given code isn't a prefix code.\n\n";


}

void strcpy2(char *d, string s) {
    int len=s.size(),i;
    for(i=0;i<len;++i)
        d[i]=s[i];
    d[i]='\0';
}

bool mystrncmp(char const* s1, char const* s2, int n) {
    for(int i=0; i < n; ++i){
        if(s1[i] != s2[i])
            return false;
        if(s1[i] == '\0' || s2[i] == '\0')
            break;
    }
    return true;
}