Home | History | Annotate | Download | only in data
      1 /*
      2  * Copyright (C) 2013 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.android.camera.data;
     18 
     19 import android.database.Cursor;
     20 import android.graphics.Bitmap;
     21 import android.graphics.BitmapFactory;
     22 import android.net.Uri;
     23 
     24 import com.android.camera.debug.Log;
     25 import com.android.camera.util.Size;
     26 
     27 import java.util.Date;
     28 
     29 public class PhotoDataFactory {
     30     private static final Log.Tag TAG = new Log.Tag("PhotoDataFact");
     31 
     32     public FilmstripItemData fromCursor(Cursor c) {
     33         long id = c.getLong(PhotoDataQuery.COL_ID);
     34         String title = c.getString(PhotoDataQuery.COL_TITLE);
     35         String mimeType = c.getString(PhotoDataQuery.COL_MIME_TYPE);
     36         long dateTakenInMilliSeconds = c.getLong(PhotoDataQuery.COL_DATE_TAKEN);
     37         long dateModifiedInSeconds = c.getLong(PhotoDataQuery.COL_DATE_MODIFIED);
     38         Date creationDate = new Date(dateTakenInMilliSeconds);
     39         Date lastModifiedDate = new Date(dateModifiedInSeconds * 1000);
     40 
     41         String filePath = c.getString(PhotoDataQuery.COL_DATA);
     42         int orientation = c.getInt(PhotoDataQuery.COL_ORIENTATION);
     43         int width = c.getInt(PhotoDataQuery.COL_WIDTH);
     44         int height = c.getInt(PhotoDataQuery.COL_HEIGHT);
     45 
     46         Size dimensions;
     47         // If the width or height is unknown, attempt to decode it from
     48         // the physical bitmaps.
     49         if (width <= 0 || height <= 0) {
     50 
     51             Log.w(TAG, "Zero dimension in ContentResolver for "
     52                   + filePath + ":" + width + "x" + height);
     53 
     54             dimensions = decodeBitmapDimensions(filePath);
     55             if (dimensions == null) {
     56                 // If we are unable to decode non-zero bitmap dimensions
     57                 // we should not create a filmstrip item data for this
     58                 // entry in the media store.
     59                 return null;
     60             }
     61         } else {
     62             dimensions = new Size(width, height);
     63         }
     64 
     65         long sizeInBytes = c.getLong(PhotoDataQuery.COL_SIZE);
     66         double latitude = c.getDouble(PhotoDataQuery.COL_LATITUDE);
     67         double longitude = c.getDouble(PhotoDataQuery.COL_LONGITUDE);
     68         Location location = Location.from(latitude, longitude);
     69 
     70         Uri uri = PhotoDataQuery.CONTENT_URI.buildUpon().appendPath(String.valueOf(id)).build();
     71 
     72         return new FilmstripItemData(
     73               id,
     74               title,
     75               mimeType,
     76               creationDate,
     77               lastModifiedDate,
     78               filePath,
     79               uri,
     80               dimensions,
     81               sizeInBytes,
     82               orientation,
     83               location);
     84     }
     85 
     86     /**
     87      * Given a file path, decode the bitmap dimensions if possible.
     88      */
     89     private Size decodeBitmapDimensions(String filePath) {
     90         int width;
     91         int height;
     92 
     93         // Ensure we only decode the dimensions, not the whole
     94         // file if at all possible.
     95         BitmapFactory.Options opts = new BitmapFactory.Options();
     96         opts.inJustDecodeBounds = true;
     97         BitmapFactory.decodeFile(filePath, opts);
     98         if (opts.outWidth > 0 && opts.outHeight > 0) {
     99             width = opts.outWidth;
    100             height = opts.outHeight;
    101         } else {
    102             Log.w(TAG, "Dimension decode failed for " + filePath);
    103 
    104             // Fall back on decoding the entire file
    105             Bitmap b = BitmapFactory.decodeFile(filePath);
    106             if (b == null) {
    107                 Log.w(TAG, "PhotoData skipped."
    108                       + " Decoding " + filePath + " failed.");
    109                 return null;
    110             }
    111             width = b.getWidth();
    112             height = b.getHeight();
    113             if (width == 0 || height == 0) {
    114                 Log.w(TAG, "PhotoData skipped. Bitmap size 0 for " + filePath);
    115                 return null;
    116             }
    117         }
    118 
    119         return new Size(width, height);
    120     }
    121 }