Program: 170576
Project: 170576
Buggy source:
/** 
 * Decodes an input byte array and outputs a Bitmap that is ready to be displayed. The difference with   {@link android.graphics.BitmapFactory#decodeByteArray(byte[],int,int)}is that this cares about orientation, reading it from the EXIF header. This is executed in a background thread, and returns the result to the original thread. This ignores flipping at the moment. TODO care about flipping using Matrix.scale()
 * @param source a JPEG byte array
 * @param callback a callback to be notified
 */
public static void decodeBitmap(final byte[] source,final BitmapCallback callback){
  final Handler ui=new Handler();
  new Thread(new Runnable(){
    @Override public void run(){
      int orientation=0;
      boolean flip=false;
      try {
        ExifInterface exif=new ExifInterface(new ByteArrayInputStream(source));
        Integer exifOrientation=exif.getAttributeInt(ExifInterface.TAG_ORIENTATION,ExifInterface.ORIENTATION_NORMAL);
switch (exifOrientation) {
case ExifInterface.ORIENTATION_NORMAL:
case ExifInterface.ORIENTATION_FLIP_HORIZONTAL:
          orientation=0;
        break;
case ExifInterface.ORIENTATION_ROTATE_180:
case ExifInterface.ORIENTATION_FLIP_VERTICAL:
      orientation=180;
    break;
case ExifInterface.ORIENTATION_ROTATE_90:
case ExifInterface.ORIENTATION_TRANSPOSE:
  orientation=90;
break;
case ExifInterface.ORIENTATION_ROTATE_270:
case ExifInterface.ORIENTATION_TRANSVERSE:
orientation=270;
break;
default :
orientation=0;
}
flip=exifOrientation == ExifInterface.ORIENTATION_FLIP_HORIZONTAL || exifOrientation == ExifInterface.ORIENTATION_FLIP_VERTICAL || exifOrientation == ExifInterface.ORIENTATION_TRANSPOSE || exifOrientation == ExifInterface.ORIENTATION_TRANSVERSE;
}
 catch (IOException e) {
e.printStackTrace();
orientation=0;
flip=false;
}
Bitmap bitmap=BitmapFactory.decodeByteArray(source,0,source.length);
if (orientation != 0 || flip) {
Matrix matrix=new Matrix();
matrix.setRotate(orientation);
Bitmap temp=bitmap;
bitmap=Bitmap.createBitmap(bitmap,0,0,bitmap.getWidth(),bitmap.getHeight(),matrix,true);
temp.recycle();
}
final Bitmap result=bitmap;
ui.post(new Runnable(){
@Override public void run(){
callback.onBitmapReady(result);
}
}
);
}
}
).start();
}

Fixed version (ground truth):
static Bitmap decodeBitmap(byte[] source){
  int orientation;
  boolean flip;
  InputStream stream=null;
  try {
    stream=new ByteArrayInputStream(source);
    ExifInterface exif=new ExifInterface(stream);
    Integer exifOrientation=exif.getAttributeInt(ExifInterface.TAG_ORIENTATION,ExifInterface.ORIENTATION_NORMAL);
switch (exifOrientation) {
case ExifInterface.ORIENTATION_NORMAL:
case ExifInterface.ORIENTATION_FLIP_HORIZONTAL:
      orientation=0;
    break;
case ExifInterface.ORIENTATION_ROTATE_180:
case ExifInterface.ORIENTATION_FLIP_VERTICAL:
  orientation=180;
break;
case ExifInterface.ORIENTATION_ROTATE_90:
case ExifInterface.ORIENTATION_TRANSPOSE:
orientation=90;
break;
case ExifInterface.ORIENTATION_ROTATE_270:
case ExifInterface.ORIENTATION_TRANSVERSE:
orientation=270;
break;
default :
orientation=0;
}
flip=exifOrientation == ExifInterface.ORIENTATION_FLIP_HORIZONTAL || exifOrientation == ExifInterface.ORIENTATION_FLIP_VERTICAL || exifOrientation == ExifInterface.ORIENTATION_TRANSPOSE || exifOrientation == ExifInterface.ORIENTATION_TRANSVERSE;
}
 catch (IOException e) {
e.printStackTrace();
orientation=0;
flip=false;
}
 finally {
if (stream != null) {
try {
stream.close();
}
 catch (Exception e) {
}
}
}
Bitmap bitmap=BitmapFactory.decodeByteArray(source,0,source.length);
if (orientation != 0 || flip) {
Matrix matrix=new Matrix();
matrix.setRotate(orientation);
Bitmap temp=bitmap;
bitmap=Bitmap.createBitmap(bitmap,0,0,bitmap.getWidth(),bitmap.getHeight(),matrix,true);
temp.recycle();
}
return bitmap;
}