wtorek, stycznia 15, 2013

Hackowanie odczytu danych Exif ;-)

Walczę nad kilkoma nowymi rzeczami do Bloggeroida.
Jedną z nich jest dodawanie wielu obrazków naraz.
I właśnie w trakcie implementowania natrafiłem na dziwne zjawisko. Obrazki dodawały się bardzo szybko, ale mój kod odpowiedzialny za odczytanie danych Exif potrzebował masy czasu na przetworzenie wielu obrazków.
Miałem pewne przypuszczenia, ale nie miałem pewności ;-)
Dziś sprawdziłem i okazało się, że drań za każdym razem czytał po 17 (do 64) KB danych, a i tak operował zwykle na pierwszych 1024 bajtach....
No to zmieniłem kod tak, że ze strumienia czytam tylko pierwsze 1024 bajty, a w razie będę potrzebował w trakcie operacji dodatkowych danych to je sobie doczytuję ;-)

Stąd metoda:

static long get32u(int oset, Section s, boolean motorolaOrder) throws IOException {
return get32s(oset, s, motorolaOrder);
}

Zmienił się w:

static long get32u(int oset, Section s, boolean motorolaOrder) throws IOException {
ensure(s, oset);
return get32s(oset, s, motorolaOrder);
}

Gdzie metoda ensure wygląda tak:

static void ensure(Section s, int pos) throws IOException {
if ((pos+4)>s.lastPos) {
int last = ((pos/1024)+1)*1024;
if (last>s.itemLeng) last =s.itemLeng;
s.fis.read(s.data, s.lastPos, last-(s.lastPos-1));
s.lastPos=last;
}
}

Niecne działanie ensure polega na tym, że sprawdza czy aby nie próbujemy dobrać się do danych, które nie zostały jeszcze wczytane i w razie czego je doczytuje ;-)
Żadna filozofia, a wydajnościowo powinno pomóc ;-)

Na emulatorze kod działa, teraz będzie trzeba go wrzucić na prawdziwego Androida ;p


Podobne postybeta
Lenistwo w działaniu, "piklujemy" Androida ;-)
Wredne Google Docs
Exif jest zły - część 2 :-)
Tworzenie poprawnych nazw plików :-)
Przesyłanie "obcych" na odległość, albo uniwersalny format danych ;-)