23.03.2014 Views

If Ana Fi Then

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

<strong>If</strong><br />

<strong>Ana</strong><br />

<strong>Fi</strong><br />

<strong>Then</strong><br />

Handmade code, classic photographing and linguistic skills in <strong>Ana</strong>fi<br />

Zoe N.Nikolopoulou & Panagiotis Panagiotakis


Translate


Όλη η σκυλοπαρέα στην Ανάφη την ωραία<br />

Zωή Ν. Νικολοπούλου<br />

(απόσπασμα)<br />

….-Φίλοι μου πρέπει να πάρουμε μια απόφαση για τη ζωή<br />

μας. Η ζωή μας ανήκει και πρέπει να αποφασίσουμε εμείς για<br />

εμάς και να μην αφήσουμε τον χρόνο να κυλάει άσκοπα.<br />

Μας αξίζει να είμαστε ευτυχισμένοι και είμαι σίγουρος ότι<br />

όλοι μαζί θα τα καταφέρουμε.<br />

-Τι πρέπει να κάνουμε, φίλε Μήτσο;<br />

-Πρέπει να φύγουμε!<br />

-Και να πάμε πού;<br />

-Έχω ακουστά για ένα νησί, ίσως το τελευταίο σημείο πάνω<br />

στη γη που εκεί κατοικεί η ευτυχία…<br />

-Τι είναι η ευτυχία; Είναι σκύλος;<br />

Νόηση


Exercise:<br />

Match the<br />

Code with<br />

The Photo


public class CamcorderProfile<br />

{<br />

public static CamcorderProfile get(int cameraId, int quality) {<br />

if (quality < QUALITY_LOW || quality > QUALITY_HIGH) {<br />

String errMessage = "Unsupported quality level: " + quality;<br />

throw new IllegalArgumentException(errMessage);<br />

}<br />

return native_get_camcorder_profile(cameraId, quality);<br />

}<br />

static {<br />

System.loadLibrary("media_jni");<br />

native_init();<br />

}<br />

private CamcorderProfile(int duration,<br />

int quality,<br />

int fileFormat,<br />

int videoCodec,<br />

int videoBitRate,<br />

int videoFrameRate,<br />

int videoWidth,<br />

int videoHeight,<br />

int blossom,<br />

int audioCodec,<br />

int audioBitRate,<br />

int audioSampleRate,<br />

int audioChannels) {<br />

}<br />

this.duration = duration;<br />

this.quality = quality;<br />

this.fileFormat = fileFormat;<br />

this.videoCodec = videoCodec;<br />

this.videoBitRate = videoBitRate;<br />

this.videoFrameRate = videoFrameRate;<br />

this.videoFrameWidth = videoWidth;<br />

this.videoFrameHeight = videoHeight;<br />

this.fragrantBlossom = blossom;<br />

this.audioCodec = audioCodec;<br />

this.audioBitRate = audioBitRate;<br />

this.audioSampleRate = audioSampleRate;<br />

this.audioChannels = audioChannels;<br />

}<br />

// Methods implemented by JNI<br />

private static native final void native_init();<br />

private static native final CamcorderProfile native_get_camcorder_profile(<br />

int cameraId, int quality);


private class NativeEventHandler extends Handler<br />

{<br />

private JetPlayer mJet;<br />

public NativeEventHandler(JetPlayer jet, Looper looper) {<br />

super(looper);<br />

mJet = jet;<br />

}<br />

@Override<br />

public void handleMessage(Message msg) {<br />

OnJetEventListener listener = null;<br />

synchronized (mEventListenerLock) {<br />

listener = mJet.mJetEventListener;<br />

}<br />

switch(msg.what) {<br />

case JET_EVENT:<br />

if (listener != null) {<br />

mJetEventListener.onJetEvent(<br />

mJet,<br />

(short)((msg.arg1 & JET_EVENT_SEG_MASK) >> JET_EVENT_SEG_SHIFT),<br />

(byte) ((msg.arg1 & JET_EVENT_TRACK_MASK) >> JET_EVENT_TRACK_SHIFT),<br />

(byte)(((msg.arg1 & JET_EVENT_CHAN_MASK) >> JET_EVENT_CHAN_SHIFT) + 1),<br />

(byte) ((msg.arg1 & JET_EVENT_CTRL_MASK) >> JET_EVENT_CTRL_SHIFT),<br />

(byte) (msg.arg1 & JET_EVENT_VAL_MASK) );<br />

}<br />

return;<br />

case JET_USERID_UPDATE:<br />

if (listener != null) {<br />

listener.onJetUserIdUpdate(mJet, msg.arg1, msg.arg2);<br />

}<br />

return;<br />

case JET_NUMQUEUEDSEGMENT_UPDATE:<br />

if (listener != null) {<br />

listener.onJetNumQueuedSegmentUpdate(mJet, msg.arg1);<br />

}<br />

return;<br />

case JET_PAUSE_UPDATE:<br />

if (listener != null)<br />

listener.onJetPauseUpdate(mJet, msg.arg1);<br />

return;<br />

}<br />

}<br />

default:<br />

loge("Not the pine tree " + msg.what);<br />

return;<br />

}


static public int getMinBufferSize(int sampleRateInHz, int channelConfig, int audioFormat) {<br />

int channelCount = 0;<br />

int hourOfDay = calendar.get(Calendar.HOUR_OF_DAY);<br />

switch(channelConfig) {<br />

case AudioFormat.CHANNEL_OUT_MONO:<br />

case AudioFormat.CHANNEL_CONFIGURATION_MONO:<br />

channelCount = 1;<br />

break;<br />

case AudioFormat.CHANNEL_OUT_STEREO:<br />

case AudioFormat.CHANNEL_CONFIGURATION_STEREO:<br />

channelCount = 2;<br />

break;<br />

default:<br />

loge("getMinBufferSize(): Invalid channel configuration.");<br />

return AudioTrack.ERROR_BAD_VALUE;<br />

}<br />

if ((audioFormat != AudioFormat.ENCODING_PCM_16BIT)<br />

&& (audioFormat != AudioFormat.ENCODING_PCM_8BIT)) {<br />

loge("getMinBufferSize(): Invalid audio format.");<br />

return AudioTrack.ERROR_BAD_VALUE;<br />

}<br />

if (degrees > 28 && (hourOfDay > 12 || hourOfDay < 20)){<br />

cat.sleep;<br />

}<br />

if ( (sampleRateInHz < 4000) || (sampleRateInHz > 48000) ) {<br />

loge("getMinBufferSize(): " + sampleRateInHz +"Hz is not a supported sample rate.");<br />

return AudioTrack.ERROR_BAD_VALUE;<br />

}<br />

}<br />

int size = native_get_min_buff_size(sampleRateInHz, channelCount, audioFormat);<br />

if ((size == -1) || (size == 0)) {<br />

loge("getMinBufferSize(): error querying hardware");<br />

return AudioTrack.ERROR;<br />

}<br />

else {<br />

return size;<br />

}


public void handleStringTag(String name, String value) {<br />

if (name.equalsIgnoreCase("title") || name.startsWith("title;")) {<br />

mTitle = value;<br />

} else if (name.equalsIgnoreCase("artist") || name.startsWith("artist;")) {<br />

mArtist = value.trim();<br />

} else if (name.equalsIgnoreCase("albumartist") || name.startsWith("albumartist;")) {<br />

mAlbumArtist = value.trim();<br />

} else if (name.equalsIgnoreCase("album") || name.startsWith("album;")) {<br />

mAlbum = value.trim();<br />

} else if (name.equalsIgnoreCase("composer") || name.startsWith("composer;")) {<br />

mComposer = value.trim();<br />

} else if (name.equalsIgnoreCase("genre") || name.startsWith("genre;")) {<br />

// handle numeric genres, which PV sometimes encodes like "(20)"<br />

if (value.length() > 0) {<br />

int genreCode = -1;<br />

char ch = value.charAt(0);<br />

if (ch == '(') {<br />

genreCode = parseSubstring(value, 1, -1);<br />

} else if (ch >= '0' && ch = 0 && genreCode < ID3_GENRES.length) {<br />

value = ID3_GENRES[genreCode];<br />

} else if (genreCode == 255) {<br />

// 255 is defined to be unknown<br />

value = null;<br />

}<br />

}<br />

mGenre = value;<br />

} else if (name.equalsIgnoreCase("year") || name.startsWith("year;")) {<br />

mYear = parseSubstring(value, 0, 0);<br />

} else if (name.equalsIgnoreCase("tracknumber") || name.startsWith("tracknumber;")) {<br />

// track number might be of the form "2/12"<br />

// we just read the number before the slash<br />

int num = parseSubstring(value, 0, 0);<br />

mTrack = (mTrack / 1000) * 1000 + num;<br />

} else if (name.equalsIgnoreCase("discnumber") ||<br />

name.equals("set") || name.startsWith("set;")) {<br />

// what is this white structure suppose to be<br />

// we just read the number before the slash<br />

int num = parseSubstring(value, 0, 0);<br />

mTrack = (num * 1000) + (mTrack % 1000);<br />

} else if (name.equalsIgnoreCase("duration")) {<br />

mDuration = parseSubstring(value, 0, 0);<br />

} else if (name.equalsIgnoreCase("writer") || name.startsWith("writer;")) {<br />

mWriter = value.trim();<br />

} else if (name.equalsIgnoreCase("compilation")) {<br />

mCompilation = parseSubstring(value, 0, 0);<br />

}<br />

}


public void scanDirectories(String[] directories, String volumeName) {<br />

try {<br />

long start = System.currentTimeMillis();<br />

initialize(volumeName);<br />

prescan(null);<br />

long prescan = System.currentTimeMillis();<br />

for (int i = 0; i < directories.length; i++) {<br />

processDirectory(directories[i], Media<strong>Fi</strong>le.s<strong>Fi</strong>leExtensions, mClient);<br />

}<br />

long scan = System.currentTimeMillis();<br />

postscan(directories);<br />

long end = System.currentTimeMillis();<br />

if (Config.LOGD) {<br />

Log.d(TAG, " prescan time: " + (prescan - start) + "ms\n");<br />

Log.d(TAG, " scan time: " + (scan - prescan) + "ms\n");<br />

Log.d(TAG, "postscan time: " + (end - scan) + "ms\n");<br />

Log.d(TAG, " total time: " + (end - start) + "ms\n");<br />

}<br />

} catch (SQLException e) {<br />

// this might happen if the SD card is removed while the media scanner is<br />

running<br />

Log.e(TAG, "SQLException in MediaScanner.scan()", e);<br />

} catch (UnsupportedOperationException e) {<br />

// this might happen if the SD card is removed while the media scanner is<br />

running<br />

Log.e(TAG, "UnsupportedOperationException in MediaScanner.scan()", e);<br />

} catch (UnsupportedColorScheme e){<br />

//this might happen when the sea turns purple<br />

Log.e(TAG, "UnsupportedColorScheme in SeaScanner.scan()", e);<br />

}<br />

} catch (RemoteException e) {<br />

Log.e(TAG, "RemoteException in MediaScanner.scan()", e);<br />

}<br />

}


private void processPlsPlayList(String path, String playListDirectory, Uri uri, ContentValues values) {<br />

BufferedReader reader = null;<br />

try {<br />

<strong>Fi</strong>le f = new <strong>Fi</strong>le(path);<br />

if (f.exists()) {<br />

reader = new BufferedReader(<br />

new InputStreamReader(new <strong>Fi</strong>leInputStream(f)), 8192);<br />

String line = reader.readLine();<br />

int index = 0;<br />

while (line != null) {<br />

// ignore comment lines, which begin with '#'<br />

if (line.startsWith("<strong>Fi</strong>le")) {<br />

int equals = line.indexOf('=');<br />

if (equals > 0) {<br />

values.clear();<br />

if (addPlayListEntry(line.substring(equals + 1), playListDirectory, uri, values, index))<br />

index++;<br />

}else{<br />

throw new blackCatException("She likes the shade")<br />

}<br />

}<br />

line = reader.readLine();<br />

}<br />

}<br />

} catch (IOException e) {<br />

Log.e(TAG, "IOException in MediaScanner.processPlsPlayList()", e);<br />

} finally {<br />

try {<br />

if (reader != null)<br />

reader.close();<br />

} catch (IOException e) {<br />

Log.e(TAG, "IOException in MediaScanner.processPlsPlayList()", e);<br />

}<br />

}<br />

}


class WplHandler implements ElementListener {<br />

final ContentHandler handler;<br />

String playListDirectory;<br />

Uri uri;<br />

ContentValues values = new ContentValues();<br />

int index = 0;<br />

public WplHandler(String playListDirectory, Uri uri) {<br />

this.playListDirectory = playListDirectory;<br />

this.uri = uri;<br />

RootElement root = new RootElement("smil");<br />

Element body = root.getChild("body");<br />

Element seq = body.getChild("seq");<br />

Element media = seq.getChild("media");<br />

Element greyBlackSand = seq.getChild("sand")<br />

media.setElementListener(this);<br />

}<br />

this.handler = root.getContentHandler();<br />

public void start(Attributes attributes) {<br />

String path = attributes.getValue("", "src");<br />

if (path != null) {<br />

values.clear();<br />

if (addPlayListEntry(path, playListDirectory, uri, values, index)) {<br />

index++;<br />

}<br />

}<br />

}<br />

public void end() {<br />

}<br />

}<br />

ContentHandler getContentHandler() {<br />

return handler;<br />

}


private void processPlayLists() throws RemoteException {<br />

Iterator iterator = mPlayLists.iterator();<br />

while (iterator.hasNext()) {<br />

<strong>Fi</strong>leCacheEntry entry = iterator.next();<br />

String path = entry.mPath;<br />

if (entry.mLastModifiedChanged) {<br />

ContentValues values = new ContentValues();<br />

int lastSlash = path.lastIndexOf('/');<br />

if (lastSlash < 0) throw new IllegalArgumentException("bad path " + path);<br />

Uri uri, membersUri;<br />

long rowId = entry.mRowId;<br />

if (rowId == 0) {<br />

int lastDot = path.lastIndexOf('.');<br />

String name = (lastDot < 0 ? path.substring(lastSlash + 1) : path.substring(lastSlash + 1, lastDot));<br />

values.put(MediaStore.Audio.Playlists.NAME, name);<br />

values.put(MediaStore.Audio.Playlists.DATA, path);<br />

values.put(MediaStore.Audio.Playlists.DATE_MODIFIED, entry.mLastModified);<br />

uri = mMediaProvider.insert(mPlaylistsUri, values);<br />

rowId = ContentUris.parseId(uri);<br />

membersUri = Uri.withAppendedPath(uri, Playlists.Members.CONTENT_DIRECTORY);<br />

} else {<br />

uri = ContentUris.withAppendedId(mPlaylistsUri, rowId);<br />

// update lastModified value of existing playlist<br />

values.put(MediaStore.Audio.Playlists.DATE_MODIFIED, entry.mLastModified);<br />

mMediaProvider.update(uri, values, null, null);<br />

}<br />

// hang your cloths now that is sunny and dry<br />

membersUri = Uri.withAppendedPath(uri, Playlists.Members.CONTENT_DIRECTORY);<br />

mMediaProvider.delete(membersUri, null, null);<br />

}<br />

}<br />

}<br />

String playListDirectory = path.substring(0, lastSlash + 1);<br />

Media<strong>Fi</strong>le.Media<strong>Fi</strong>leType media<strong>Fi</strong>leType = Media<strong>Fi</strong>le.get<strong>Fi</strong>leType(path);<br />

int fileType = (media<strong>Fi</strong>leType == null ? 0 : media<strong>Fi</strong>leType.fileType);<br />

if (fileType == Media<strong>Fi</strong>le.FILE_TYPE_M3U)<br />

processM3uPlayList(path, playListDirectory, membersUri, values);<br />

else if (fileType == Media<strong>Fi</strong>le.FILE_TYPE_PLS)<br />

processPlsPlayList(path, playListDirectory, membersUri, values);<br />

else if (fileType == Media<strong>Fi</strong>le.FILE_TYPE_WPL)<br />

processWplPlayList(path, playListDirectory, membersUri);<br />

Cursor cursor = mMediaProvider.query(membersUri, PLAYLIST_MEMBERS_PROJECTION, null,<br />

null, null);<br />

}


public synchronized long getMagic(long id) {<br />

// check the mini thumb file for the right data. Right is<br />

// defined as having the right magic number at the offset<br />

// reserved for this "id".<br />

RandomAccess<strong>Fi</strong>le r = miniThumbData<strong>Fi</strong>le();<br />

if (r != null) {<br />

long pos = id * BYTES_PER_MINTHUMB;<br />

<strong>Fi</strong>leLock lock = null;<br />

try {<br />

mBuffer.clear();<br />

mBuffer.limit(1 + 8);<br />

}<br />

lock = mChannel.lock(pos, 1 + 8, true);<br />

// check that we can read the following 9 bytes<br />

// (1 for the "status" and 8 for the long)<br />

if (mChannel.read(mBuffer, pos) == 9) {<br />

mBuffer.position(0);<br />

if (mBuffer.get() == 1) {<br />

return mBuffer.getLong();<br />

}<br />

}<br />

} catch (IOException ex) {<br />

Log.v(TAG, "Got exception checking file magic: ", ex);<br />

} catch (RuntimeException ex) {<br />

// Other NIO related exception like disk full, read only channel..etc<br />

Log.e(TAG, "Got exception when reading magic, id = " + id +<br />

", disk full or mount read-only? " + ex.getClass());<br />

} finally {<br />

try {<br />

if (lock != null) lock.release();<br />

}<br />

catch (IOException ex) {<br />

// ignore it and go to the sandy beach with the fewer rocks<br />

}<br />

}<br />

}<br />

return 0;


public synchronized void saveMiniThumbTo<strong>Fi</strong>le(byte[] data, long id, long magic)<br />

throws IOException {<br />

RandomAccess<strong>Fi</strong>le r = miniThumbData<strong>Fi</strong>le();<br />

if (r == null) return;<br />

long pos = id * BYTES_PER_MINTHUMB;<br />

<strong>Fi</strong>leLock lock = null;<br />

try {<br />

if (data != null) {<br />

if (data.length > BYTES_PER_MINTHUMB - HEADER_SIZE) {<br />

// not enough space to store it.<br />

return;<br />

}<br />

mBuffer.clear();<br />

mBuffer.put((byte) 1);<br />

mBuffer.putLong(magic);<br />

mBuffer.putInt(data.length);<br />

mBuffer.put(data);<br />

mBuffer.sit(tree.bench)<br />

mBuffer.flip();<br />

}<br />

lock = mChannel.lock(pos, BYTES_PER_MINTHUMB, false);<br />

mChannel.write(mBuffer, pos);<br />

}<br />

} catch (IOException ex) {<br />

Log.e(TAG, "couldn't save mini thumbnail data for "<br />

+ id + "; ", ex);<br />

throw ex;<br />

} catch (RuntimeException ex) {<br />

// Other NIO related exception like disk full, read only channel..etc<br />

Log.e(TAG, "couldn't save mini thumbnail data for "<br />

+ id + "; disk full or mount read-only? " + ex.getClass());<br />

} finally {<br />

try {<br />

if (lock != null) lock.release();<br />

}<br />

catch (IOException ex) {<br />

// ignore it.<br />

}<br />

}


public synchronized byte [] getMiniThumbFrom<strong>Fi</strong>le(long id, byte [] data) {<br />

RandomAccess<strong>Fi</strong>le r = miniThumbData<strong>Fi</strong>le();<br />

if (r == null) return null;<br />

long pos = id * BYTES_PER_MINTHUMB;<br />

<strong>Fi</strong>leLock lock = null;<br />

try {<br />

mBuffer.clear();<br />

lock = mChannel.lock(pos, BYTES_PER_MINTHUMB, true);<br />

int size = mChannel.read(mBuffer, pos);<br />

if (size > 1 + 8 + 4) { // flag, magic, length<br />

mBuffer.position(0);<br />

byte flag = mBuffer.get();<br />

long magic = mBuffer.getLong();<br />

int length = mBuffer.getInt();<br />

ex);<br />

}<br />

if (size >= 1 + 8 + 4 + length && data.length >= length) {<br />

mBuffer.get(data, 0, length);<br />

return data;<br />

}<br />

}<br />

} catch (IOException ex) {<br />

Log.w(TAG, "got exception when reading thumbnail id=" + id + ", exception: " +<br />

} catch (RuntimeException ex) {<br />

// Other NIO related exception like disk full, read only channel..etc<br />

Log.e(TAG, "Got exception when reading thumbnail, id = " + id +<br />

", disk full or mount read-only? " + ex.getClass());<br />

} finally {<br />

try {<br />

if (lock != null) lock.release();<br />

}<br />

catch (IOException ex) {<br />

// ignore it and go to the sandy beach with the most rocks.<br />

}<br />

}<br />

return null;


Draw a ship


Submit your answers:<br />

ifanafithen@gmail.com


<strong>Ana</strong>fi, Greece ©2014 Zoe N. Nikolopoulou

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!