Login| Sign Up| Help| Contact|

Patent Searching and Data


Title:
SYSTEM AND METHOD FOR LINKING AND MANAGING AUDIO, IMAGE, AND TEXT DATA ON AN IPOD
Document Type and Number:
WIPO Patent Application WO/2007/095025
Kind Code:
A3
Abstract:
A system and method are provided for converting, linking, and managing different types of data files relating to a common subject on an iPod. An iPod can be used to select a subject of interest to a user, and then play back audio data or video relating to the subject, or to display images or text relating to the subject. In this manner, an iPod may be used to access information in multiple data formats relating to subjects such as, for example, a travel guide, a nature and field guide, a restaurant guide, an entertainment guide, a medical reference guide, a professional training guide, or a study guide relating to a university course.

Inventors:
WILLIAMS S MARK (US)
MACE ANDREW CARTER (US)
O'KEEFE NATE (US)
Application Number:
PCT/US2007/003246
Publication Date:
May 02, 2008
Filing Date:
February 06, 2007
Export Citation:
Click for automatic bibliography generation   Help
Assignee:
MODALITY LLC (US)
WILLIAMS S MARK (US)
MACE ANDREW CARTER (US)
O'KEEFE NATE (US)
International Classes:
H04L29/08
Other References:
JEREMY HORWITZ: "The Free iPod Book and Back to School Guide", ILOUNGE.COM, 14 August 2005 (2005-08-14), internet, XP002464618, Retrieved from the Internet [retrieved on 20080109]
EGIDI L ET AL: "Entertainment everywhere - Bringing multimedia contents into MP3 files", IEEE COMMUNICATIONS MAGAZINE, IEEE SERVICE CENTER, PISCATAWAY, US, vol. 43, no. 5, May 2005 (2005-05-01), pages 90 - 97, XP011134850, ISSN: 0163-6804
Attorney, Agent or Firm:
INTELLECTUAL PROPERTY/TECHNOLOGY LAW (Research Triangle Park, NC, US)
Download PDF:
Claims:

WHAT IS CLAIMED IS:

1. A system configured for receiving downloadable files, the system being hand- holdable, and the system comprising: a data port for receiving a transfer of at least a first downloadable file and a second downloadable file; a link module for linking the first downloadable file to the second downloadable file; an audio output port for playback of audio data; and a user interface for displaying visible data, wherein each of the first and second downloadable files includes a data type selected from the group consisting of audio data, text data, image data, and video data, and wherein the data type included in the first downloadable file is not the same as the data type included in the second downloadable file.

2. The system of claim 1 , wherein the system includes an iPod.

3. The system of claim 1 , wherein each of the at least first and second downloadable files includes data relating to a common subject.

4. The system of claim 3, wherein the common subject is selected from the group consisting of a travel guide, a nature and field guide, a restaurant guide, an entertainment guide, a medical reference guide, a professional training guide, and a study guide relating to a university course.

5. The system of claim 3, wherein the user interface is configured to display an icon relating to the common subject and to enable a user to select the icon, wherein when a user selects the icon, the user interface is further configured to display selectable items, each selectable item relating to one of the at least first and second downloadable files.

6. The system of claim 5, wherein when a user selects a selectable item relating to a downloadable file that includes audio data, the system is configured to play back the audio data via the audio output port; and when a user selects a selectable item relating to a downloadable file that includes text data or image data, the system is configured to display the text data or image data via the user interface; and when a user selects a selectable item relating to a downloadable file that includes video data, the system is configured to play back the video data via the user interface.

7. A method of providing data to a user, the data comprising at least two data types selected from the group consisting of audio data, text data, image data, and video data, the data relating to a common subject, and the method comprising the steps of: deriving a first data file having a first data type from the data relating to the common subject; deriving a second data file having a second data type from the data relating to the common subject, the second data type being different than the first data type;

combining the first and second data files into a single combined file; extracting the first and second data files from the combined file; downloading the first and second data files to a hand-holdable device; enabling a user to use the hand-holdable device to select the common subject; and when the common subject is selected, providing access to the data included in each of the first and second data files via the hand-holdable device.

8. The method of claim 7, the method further comprising the steps of: deriving a third data file having a third data type from the data relating to the common subject, the third data type being different than each of the first data type and the second data type; combining the third data file with the first and second data files into the single combined file; extracting the third data file from the combined file; downloading the third data file to the hand-holdable device; and when the common subject is selected, providing access to the data included in the third data file via the hand-holdable device.

9. The method of claim 8, the method further comprising the steps of: deriving a fourth data file having a fourth data type from the data relating to the common subject, the fourth data type being different than each of the first, second, and third data types; combining the fourth data file with the first, second, and third data files into the single combined file;

extracting the fourth data file from the combined file; downloading the fourth data file to the hand-holdable device; and when the common subject is selected, providing access to the data included in the fourth data file via the hand-holdable device.

10. The method of any of claim 7, claim 8, or claim 9, wherein the data files are downloaded to an iPod, and wherein the step of providing access to the data is performed using the iPod.

11. The method of any of claim 7, claim 8, or claim 9, wherein the common subject is selected from the group consisting of a travel guide, a nature and field guide, a restaurant guide, an entertainment guide, a medical reference guide, a professional training guide, and a study guide relating to a university course.

12. The method of claim 7, the method further comprising the steps of: displaying an icon relating to the common subject; enabling the user to select the icon; and when the icon is selected, displaying selectable items, each selectable item relating to one of the first and second data files.

13. The method of claim 12, wherein the step of providing access to the data further comprises the following steps: when a selectable item relating to a downloadable file that includes audio data is selected, playing back the audio data; and

when a selectable item relating to a downloadable file that includes text data or image data is selected, displaying the text data or image data; and when a selectable item relating to a downloadable file that includes video data is selected, playing back the video data.

14. A storage medium for storing software for providing data to a user, the data comprising at least two data types selected from the group consisting of audio data, text data, image data, and video data, the data relating to a common subject, the software being readable by a microprocessor, and the software including instructions for causing a microprocessor to: download a first data file, the first data file including a first data type, and the first data file including data relating to the common subject; download a second data file, the second data file including a second data type and the second data type being different than the first data type, and the second data file including data relating to the common subject; link the first data file to the second data file; enable a user to choose the common subject; and when the common subject is chosen, provide access to the data included in each of the first and second data files.

15. The storage medium of claim 14, the software further including instructions for causing a microprocessor to download a third data file, the third data file including a third data type and the third data type being different than each of the first data type and the second data type, and the third data file including data relating to the common subject.

16. The storage medium of claim 15, the software further including instructions for causing a microprocessor to download a fourth data file, the fourth data file including a fourth data type and the fourth data type being different than each of the first data type, the second data type, and the third data type, and the fourth data file including data relating to the common subject.

17. The storage medium of any of claim 14, claim 15, or claim 16, wherein the microprocessor is configured to download the data files to an iPod, and wherein the microprocessor is further configured to provide access to the data by using the iPod.

18. The storage medium of any of claim 14, claim 15, or claim 16, wherein the common subject is selected from the group consisting of a travel guide, a nature and field guide, a restaurant guide, an entertainment guide, a medical reference guide, a professional training guide, and a study guide relating to a university course.

19. The storage medium of claim 14, the software further including instructions for causing a microprocessor to: create a display of an icon relating to the common subject; enable the user to select the icon; and when the icon is selected, create a display of selectable items, each selectable item relating to one of the first and second data files.

20. The storage medium of claim 19, the software further including instructions for causing a microprocessor to execute the following actions: when a selectable item relating to a downloadable file that includes audio data is selected, play back the audio data; and when a selectable item relating to a downloadable file that includes text data or image data is selected, display the text data or image data; and when a selectable item relating to a downloadable file that includes video data is selected, play back the video data.

21. An iPod adapted for receiving linked downloadable files, each of the linked files including data that is related to a common subject, and the iPod comprising: a data port for receiving a transfer of at least a first downloadable file and a second downloadable file; a link module for linking the first downloadable file to the second downloadable file; an audio output port for playback of audio data; and a user interface for displaying visible data, wherein each of the first and second downloadable files includes a data type selected from the group consisting of audio data, text data, image data, and video data, and wherein the data type included in the first downloadable file is not the same as the data type included in the second downloadable file; and wherein the user interface is configured to display an icon relating to the common subject and to enable a user to select the icon, and wherein, when a user selects the icon, the user interface is further configured to display a plurality of selectable links, each of the plurality of

selectable links relating to one of the data types included in the at least two downloadable files, and wherein when a user selects a selectable link relating to a downloadable file that includes audio data, the iPod is configured to play back the audio data via the audio output port; and when a user selects a selectable link relating to a downloadable file that includes text data or image data, the system is configured to display the text data or image data via the user interface; and when a user selects a selectable link relating to a downloadable file that includes video data, the system is configured to play back the video data via the user interface.

22. A method of providing data via an iPod to a user, the data comprising at least two data types selected from the group consisting of audio data, text data, image data, and video data, the data relating to a common subject, and the method comprising the steps of: deriving at least a first data file having a first data type and a second data file having a second data type different from the first data type from the data relating to the common subject; combining the at least first and second data files into a single combined file; extracting the at least first and second data files from the combined file; downloading the at least first and second data files to the iPod; displaying an icon relating to the common subject; enabling a user to use the iPod to select the icon; and

when the icon is selected, displaying selectable links, each selectable link relating to one of the downloaded data files; and when a selectable link relating to a downloaded data file that includes audio data is selected, playing back the audio data; and when a selectable link relating to a downloaded data file that includes text data or image data is selected, displaying the text data or image data; and when a selectable link relating to a downloaded file that includes video data is selected, playing back the video data.

23. A storage medium for storing software for providing data via an iPod to a user, the data comprising at least two data types selected from the group consisting of audio data, text data, image data, and video data, the data relating to a common subject, the software being readable by a microprocessor, and the software including instructions for causing a microprocessor to: download at least a first data file having a first data type and a second data file having a second data type, the second data type being different than the first data type, and each of the at least first and second data files including data relating to the common subject; combine the at least first and second data files into a single combined file; use the combined file to install the at least first and second data files onto the iPod; enable a user to use the iPod to select an icon relating to the common subject; and when the icon is selected, provide access to the data included in each of the at least first and second data files via the iPod.

Description:

SYSTEM AND METHOD FOR LINKING AND MANAGING AUDIO, VIDEO, IMAGE, AND TEXT DATA ON AN iPOD

BACKGROUND OF THE INVENTION Field of the Invention

[0001] The present invention relates to an apparatus and a method for linking and managing disparate data types on a handheld device for displaying and playing back downloaded files, such as an iPod. More particularly, the invention relates to an apparatus and a method for converting, linking, and managing image, text, audio, and video data relating to a wide variety of informational categories on an iPod.

Related Art

[0002] The iPod, manufactured and sold by Apple Computer, Inc., has been a marketing phenomenon in recent years. The iPod has the capability of downloading certain types of data files, such as, for example, songs (audio data files) or a list of songs on an album (text files) or album art (image files), and then enabling a user to access the data files in the appropriate mode. For example, a user can select a downloaded song and then listen to the song using the iPod. Alternatively, the user can select a text file labeled with an album title and the iPod will display a textual list of the song titles from the album. As another example, the user can select the image file associated with the album, and the iPod will display a full-color, high-resolution image that is identical to that seen on the cover of the compact disc for the album, which is typically available in music stores.

[0003] Media types that can be purchased and played on an iPod include songs, audio books, television programs, short films, and music videos. The iPod can also display textual information or digital image data, such as a photograph taken by a digital camera. Typically, audio data files that are downloadable to an iPod generally use either a file format known as MP3, or one known as AAC. Video files that are downloadable to an iPod may use a file format known as MPEG-4. Image data files that contain digital, full-color photographs and that are downloadable to an iPod may use a bit-map file format known as RGB565. Text data files that are downloadable to an iPod may use a file format known as XML. In addition, the iPod is small, thin, and lightweight, so it can be easily carried by hand or in a shirt pocket. Finally, the iPod is reasonably priced for many consumers.

[0004] Because of its versatility in playing back and/or displaying disparate data types, including audio, text, image, and video, and because of its popularity, the iPod is a device that may lend itself to additional applications, relating to a variety of informational categories. In many instances, it would be advantageous to a user if an informational category associated with multiple files of more than one data type could be selected by category, or subject, rather than on a file-by- file basis. However, the iPod does not currently include this capability. Accordingly, the present inventors have recognized a need to enable users to access more than one data type in relation to the same information category.

SUMMARY OF THE INVENTION

[0005] In one aspect, the invention provides a system configured for receiving downloadable files. The system is hand-holdable. The system includes a data port for receiving a transfer of at least a first downloadable file and a second downloadable file; a link module for linking the first downloadable file to the second downloadable file; an audio output port for playback of audio data; and a user interface for displaying visible data. Each of the first and second downloadable files includes a data type selected from the group consisting of audio data, text data, image data, and video data. The data type included in the first downloadable file is not the same as the data type included in the second downloadable file. The system may include an iPod.

[0006] Each of the at least first and second downloadable files may include data relating to a common subject. The common subject may be selected from the group consisting of a travel guide, a nature and field guide, a restaurant guide, an entertainment guide, a medical reference guide, a professional training guide, and a study guide relating to a university course.

[0007] The user interface may be configured to display an icon relating to the common subject and to enable a user to select the icon. When a user selects the icon, the user interface may be further configured to display selectable items. Each selectable item icon may relate to one of the at least first and second downloadable files. When a user selects a selectable item relating to a downloadable file that includes audio data, the system may be configured to play back the audio data via the audio output port. When a user selects a selectable

item relating to a downloadable file that includes text data or image data, the system may be configured to display the text data or image data via the user interface. When a user selects a selectable item relating to a downloadable file that includes video data, the system may be configured to play back the video data via the user interface.

[0008] In another aspect, the invention provides a method of providing data to a user. The data includes at least two data types selected from the group consisting of audio data, text data, image data, and video data. The data relates to a common subject. The method includes the steps of deriving a first data file having a first data type from the data relating to the common subject; deriving a second data file having a second data type from the data relating to the common subject, combining the first and second data files into a single combined file; extracting the first and second data files from the combined file; downloading the first and second data files to a hand-holdable device; enabling a user to use the hand-holdable device to select the common subject; and, when the common subject is selected, providing access to the data included in each of the first and second data files via the hand-holdable device. The second data type is different than the first data type.

[0009] The method may further include the steps of deriving a third data file having a third data type from the data relating to the common subject; combining the third data file with the first and second data files into the single combined file; extracting the third data file from the combined file; downloading the third data file to the hand-holdable device; and when the common subject is

selected, providing access to the data included in the third data file via the hand- holdable device. The third data type may be different than each of the first data type and the second data type. The method may further include the steps of deriving a fourth data file having a fourth data type from the data relating to the common subject, combining the fourth data file with the first, second, and third data files into the single combined file; extracting the fourth data file from the combined file; downloading the fourth data file to the hand-holdable device; and when the common subject is selected, providing access to the data included in the fourth data file via the hand-holdable device. The fourth data type may be different than each of the first, second, and third data types. The data files may be downloaded to an iPod, The step of providing access to the data may be performed using the iPod.

[0010] The common subject may be selected from the group consisting of a travel guide, a nature and field guide, a restaurant guide, an entertainment guide, a medical reference guide, a professional training guide, and a study guide relating to a university course. The method may further include the steps of displaying an icon relating to the common subject; enabling the user to select the icon; and, when the icon is selected, displaying selectable items, each selectable item relating to one of the first and second data files. The step of providing access to the data may include the steps of playing back the audio data when a selectable item relating to a downloadable file that includes audio data is selected; displaying the text data or image data when a selectable item relating to a downloadable file that includes text data or image data is selected; and playing

back the video data when a selectable item relating to a downloadable file that includes video data is selected.

[0011] In yet another aspect of the invention, a storage medium for storing software for providing data to a user is provided. The data includes at least two data types selected from the group consisting of audio data, text data, image data, and video data. The data relates to a common subject. The software is readable by a microprocessor. The software includes instructions for causing a microprocessor to download a first data file; download a second data file; link the first data file to the second data file; enable a user to choose the common subject; and, when the common subject is chosen, provide access to the data included in each of the first and second data files. The first data file includes a first data type. The first data file includes data relating to the common subject. The second data file includes a second data type. The second data type is different than the first data type. The second data file includes data relating to the common subject.

[0012] The software may further include instructions for causing a microprocessor to download a third data file. The third data file may include a third data type. The third data type may be different than each of the first data type and the second data type. The third data file may include data relating to the common subject. The software may further include instructions for causing a microprocessor to download a fourth data file. The fourth data file may include a fourth data type. The fourth data type may be different than each of the first data type, the second data type, and the third data type. The fourth data file may

include data relating to the common subject. The microprocessor may be configured to download the data files to an iPod. The microprocessor may be further configured to provide access to the data by using the iPod.

[0013] The common subject may be selected from the group consisting of a travel guide, a nature and field guide, a restaurant guide, an entertainment guide, a medical reference guide, a professional training guide, and a study guide relating to a university course. The software may further include instructions for causing a microprocessor to create a display of an icon relating to the common subject; enable the user to select the icon; and, when the icon is selected, create a display of selectable items. Each selectable item may relate to one of the first and second data files. The software may further include instructions for causing a microprocessor to play back the audio data when a selectable item relating to a downloadable file that includes audio data is selected; display the text or image data when a selectable item relating to a downloadable file that includes text data or image data is selected; and play back the video data when a selectable item relating to a downloadable file that includes video data is selected.

[0014] In still another aspect, the invention provides an iPod adapted for receiving linked downloadable files. Each of the linked files includes data that is related to a common subject. The iPod includes a data port for receiving a transfer of at least a first downloadable file and a second downloadable file; a link module for linking the first downloadable file to the second downloadable file; an audio output port for playback of audio data; and a user interface for displaying visible data. Each of the first and second downloadable files includes a data type

selected from the group consisting of audio data, text data, image data, and video data. The data type included in the first downloadable file is not the same as the data type included in the second downloadable file. The user interface is configured to display an icon relating to the common subject and to enable a user to select the icon. When a user selects the icon, the user interface is further configured to display a plurality of selectable links. Each of the plurality of selectable links relates to one of the data types included in the at least two downloadable files. When a user selects a selectable link relating to a downloadable file that includes audio data, the iPod is configured to play back the audio data via the audio output port. When a user selects a selectable link relating to a downloadable file that includes text data or image data, the system is configured to display the text data or image data via the user interface. When a user selects a selectable link relating to a downloadable file that includes video data, the system is configured to play back the video data via the user interface.

[0015] In yet another aspect, the invention provides a method of providing data via an iPod to a user. The data includes at least two data types selected from the group consisting of audio data, text data, image data, and video data. The data relates to a common subject. The method includes the steps of deriving at least a first data file having a first data type and a second data file having a second data type different from the first data type from the data relating to the common subject; combining the at least first and second data files into a single combined file; extracting the at least first and second data files from the combined file; downloading the at least first and second data files to the iPod; displaying an icon relating to the common subject; enabling a user to use the

iPod to select the icon; and when the icon is selected, displaying selectable links. Each selectable link relates to one of the downloaded data files. When a selectable link relating to a downloaded data file that includes audio data is selected, the method further includes the step of playing back the audio data. When a selectable link relating to a downloaded data file that includes text data or image data is selected, the method further includes the step of displaying the text data or image data. When a selectable link relating to a downloaded file that includes video data is selected, the method further includes the step of playing back the video data.

[0016] In still another aspect of the invention, a storage medium for storing software for providing data via an iPod to a user is provided. The data includes at least two data types selected from the group consisting of audio data, text data, image data, and video data. The data relates to a common subject. The software is readable by a microprocessor. The software includes instructions for causing a microprocessor to download at least a first data file having a first data type and a second data file having a second data type; combine the at least first and second data files into a single combined file; use the combined file to install the at least first and second data files onto the iPod; enable a user to use the iPod to select an icon relating to the common subject; and when the icon is selected, provide access to the data included in each of the at least first and second data files via the iPod. The second data type is different than the first data type. Each of the at least first and second data files includes data relating to the common subject.

BRIEF DESCRIPTION OF THE DRAWINGS

[0017] Figure 1 is a flow diagram that illustrates a conversion process for converting a reference volume into an iPod title according to a preferred embodiment of the invention.

[0018] Figure 2 is a flow chart that illustrates a process for linking and managing disparate data types relating to a common subject according to a preferred embodiment of the invention.

[0019] Figure 3 is a flow diagram that illustrates a conversion process for converting the contents of a reference into iPod-ready files and then into a single data file having more than one data type according to a preferred embodiment of the invention.

[0020] Figure 4 is a block diagram of a system for linking and managing disparate data types according to a preferred embodiment of the invention.

[0021] Figure 5 shows how a user can select an iPod title, as generated by a system according to a preferred embodiment of the invention, to produce an image display relating to the subject of the selected iPod title.

[0022] Figure 6 shows an exemplary set of menus of subtopics and user options relating to one of the selected iPod title of Figure 5.

[0023] Figure 7 shows an exemplary selection of general interest reference titles that may be implemented on an iPod using a process according to a preferred embodiment of the invention.

[0024] Figure 8 shows an exemplary set of menus of subtopics and user options relating to one of the example reference titles shown in Figure 6.

[0025] Figures 9 and 10 show exemplary reference titles relating to specialized fields of study as implemented on an iPod using a process according to a preferred embodiment of the invention.

[0026] Figure 11 shows a selection of exemplary reference titles relating to a medical references and study guides for medical students that may be implemented on an iPod using a process according to a preferred embodiment of the invention.

[0027] Figures 12A and 12B show an exemplary educational flash card tool designed for children that may be implemented on an iPod using a process according to a preferred embodiment of the invention.

[0028] Figures 13A and 13B show an exemplary educational flash card tool designed for medical students that may be implemented on an iPod using a process according to a preferred embodiment of the invention.

[0029] Figures 14A-14C show an exemplary scrollable map tool that may be implemented on an iPod using a process according to a preferred embodiment of the invention.

[0030] Figures 15A-15C show an exemplary zoomable set of images derived from a medical reference title that may be implemented on an iPod using a process according to a preferred embodiment of the invention.

DETAILED DESCRIPTION OF THE INVENTION

[0031] The present inventors have recognized that the capability of an iPod to download disparate data types, including audio data, image data, text data, and video data, can enable the iPod to be used for a wide variety of applications for providing information access to users on almost any subject. Conventional use of the iPod has typically included songs, audio books, television programs, short films, and music videos. However, the present invention enables a user to download and access additional reference types and subject matter categories, including, for example: travel guides; nature and field guides; restaurant and entertainment guides; medical and professional reference titles; higher education supplementary media, such as flashcards, quizzes and practice examinations, and study guides; and professional training guides. In addition, the present invention contemplates providing such access via an iPod

for virtually any type of reference or subject. In a preferred embodiment, the invention is designed for optimal use on fourth- and fifth-generation iPods (also known as the "photo" iPod and the "video" iPod), as well as the iPod Naπo; i.e., any iPod that includes a color display.

[0032] Referring to Figure 1 , a flow diagram that illustrates a conversion process for converting a reference volume into an iPod title according to a preferred embodiment of the invention is shown. An educational, edutainment, or reference title 105 may typically be available in a traditional format, such as a book, a film, or a recording, and may or may not also be available in the appropriate file format. Conventionally, the iPod is configured to download any file having an MP3, MPEG4, RGB 565, or XML file format, and then to play back or display the information, depending on the data type. However, many reference titles may include information that can be presented using two or more data types. With conventional iPod files, each file can include only one data type. Therefore, if a single subject or reference title includes data having two or more types, two or more corresponding iPod files would be required. Furthermore, the conventional use of an iPod does not provide any way to link the two or more iPod files.

[0033] Accordingly, the present invention uses a conversion process 110 to take traditional multimedia content from a publisher and to convert the content into iPod-ready files. Further, the present invention uses the conversion process 110 to convert the two or more data files of different data types relating to a single reference title 105 into an "iPod title" 115. The iPod title 115 is a single

data file that includes all of the different data types relating to the same subject, i.e., the reference title 105. In a preferred embodiment, the iPod title 115 is referred to as an iPod Reference Title (IRT).

[0034] Referring to Figures 2 and 3, a flow chart 200 and flow diagram 300 for the conversion process 110 is shown. The first step 205 is to convert the content from the reference title 105 (also shown as IRT content 305) into digital data in the appropriate respective iPod file format. The result of the conversion in step 205 will be one iPod-ready file for each data type that is included in the information content associated with the reference title 105. So, for example, a reference title 105 that includes text, audio, image, and video content will yield iPod-ready files of four separate types 310, 315, 320, and 325 as a result of the digital conversion of step 205.

[0035] In addition, the step 205 of converting content from the reference title 105 into iPod-ready files may include the creation of custom images, including either thumbnail images or full-size images, that are related to the reference title 105. In this manner, a icon or a symbol for the reference title 105 may be created, in order to provide a selectable option for the iPod user who wishes to access the content of that reference title.

[0036] Then, in step 210, all of the iPod-ready files associated with a single reference title 105 are converted into binary code and combined into a single data file, i.e., IRT 115. The IRT 115 will preferably be labeled with the ".mtp" file extension to denote a "modality title package" file. By combining all of the

disparate data types into a single file, the content is effectively linked together. The IRT file 115 can preferably be labeled in a manner to indicate to a user the subject matter of the reference title 105.

[0037] Referring also to Figure 4, at step 215, a user desiring to access the reference title 105 on the user's iPod obtains a copy of the IRT file 115 associated with the reference title 105. The user may obtain the IRT file 115, for example, by purchasing the IRT file 115 via the Internet or through a traditional commercial outlet. The user downloads the IRT file 115 onto a personal computer 405. The personal computer 405 is configured to include a software module 410 that is designed for processing the IRT file 115. In a preferred embodiment, the software module 410 is known as the Modality Desktop Application (MDA).

[0038] At step 220, the MDA 410 reads the IRT file 115 and deconstructs the embedded media assets from the file 115 into the constituent iPod-ready files. Then, at step 225, the MDA 410 installs all of the iPod-ready files in an iPod 415 that is connected to the personal computer 405. The installation is effected by writing the iPod-ready files directly to an appropriate iPod database or to the Notes folder on the iPod 415. More particularly, the installation makes use of three iPod database files: iTunesDB for audio and video, ArtworkDB for album art work, and Photo Database for photographs. Each of these iPod databases is updated with specific information about each new entry, including, for example, a unique identification, byte offsets and byte lengths for RGB565 data, and title strings. In addition, other iPod system files, such as Syslnfo, are read to

determine the type of iPod upon which the installation is occurring. Each of the photo (4 th -generation) iPod, the video (5 th -generation) iPod, and the iPod Nano uses different and mutually incompatible image data formats, so the data transfer must take the destination iPod type into account. To complete the installation, text-based or Notes files are copied to the Notes folder on the iPod.

[0039] Finally, at step 230, the user can eject the iPod 415 and then use the iPod 415 as desired. Having completed the installation, the user is then able to access all of the data content associated with the original reference title 105 by navigating to the item of interest and selecting it. Upon selection, the user will be provided with a text description of the reference title 105 and selectable links to each of the individual data types that are associated with that reference title 105.

[0040] The MDA 410 is preferably implemented by the use of one or more general purpose computers 405, such as, for example, a Sun Microsystems F15k, an Apple Macintosh, or a typical personal computer manufactured by Dell, Gateway, or Hewlett-Packard. The computer 405 on which the MDA 410 is implemented can include a microprocessor. The microprocessor can be any type of processor, such as, for example, any type of general purpose microprocessor or microcontroller, a digital signal processing (DSP) processor, an application- specific integrated circuit (ASIC), a programmable read-only memory (PROM), or any combination thereof. The computer 405 may use its microprocessor to read a computer-readable medium containing software that includes instructions for carrying out one or more of the functions of the MDA 410, as described above. In a preferred embodiment, this software is written in the C language. Exemplary

code that is included in the MDA 410 in a preferred embodiment of the invention is shown in an appendix to this patent specification.

[0041] The computer 405 can also include computer memory, such as, for example, random-access memory (RAM). However, the computer memory of the computer 405 can be any type of computer memory or any other type of electronic storage medium that is located either internally or externally to the computer 405, such as, for example, read-only memory (ROM), compact disc read-only memory (CDROM), electro-optical memory, magneto-optical memory, an erasable programmable read-only memory (EPROM), an electrically-erasable programmable read-only memory (EEPROM), or the like. The computer 405 can also include a database. The database can be any type of computer database for storing, maintaining, and allowing access to electronic information stored therein. The computer 405 preferably resides on a network, such as a local area network (LAN), a wide area network (WAN), or the Internet.

[0042] The MDA 410 and the use of the IRT file 115 also enable the ability to provide digital rights management to the reference title content. For example, the IRT file 115 may contain some form of copy protection or encryption which can only be read or unencrypted by the MDA 410.

[0043] The MDA 410 provides integration with the conventional database formats that are currently used by the iPod. Because of this integration, in a preferred embodiment of the invention, installation of the linked iPod-ready files by using the MDA 410 can be performed in a simple "one-click" user operation.

In this manner, the present invention provides the advantage that installation and management of disparate media types on an iPod is simplified and easily understood by typical iPod users.

[0044] Referring to Figure 5, an example of how a user can select an IRT to produce an image display together with an audio playback is shown. User 505 is presented with a selection of IRTs 510. The user 505 selects an IRT relating to a study guide for the anatomy of the brain. As a result of this selection, the user's iPod 415 displays an image 515 of the brain, with a highlighted portion 520. In addition, as indicated by the timing bar 525, the iPod 415 plays back an audible pronunciation of the specific name for the highlighted brain area 520.

[0045] Referring to Figure 6, an illustration of how a typical user could navigate through the menus and content relating to the IRT 510 of Figure 5 is shown. At step 605, the IRT 510 is selected through the Notes menu on the iPod. Having selected the brain glossary entitled "Sylvius", a scrollable list of brain structures and terms is presented at step 610. Then, at step 615, the term "Lobes" is selected, and a brief textual description of the term is provided. In addition, two selectable links are provided: one link enables a user to obtain a view of an image of the selected brain structure, as shown in step 620; and the other link enables the user to listen to the pronunciation of the selected term.

[0046] Referring to Figure 7, three examples 705, 710, 715 of IRTs are shown. In example 705, the iPod display shows an image of a book cover for a Paris travel guide. In example 710, the iPod display shows an image of a book

cover for a wine encyclopedia. In example 715, the iPod display shows an image of a book cover for a plants and flowers compendium.

[0047] Referring to Figure 8, a cascading set of textual subtopic areas is shown to illustrate how a user can navigate through the content of an exemplary IRT. A user has selected the Paris travel guide, i.e., example 705. In the first screen 805, the book title is shown as a text entry. After selecting the book, the next text menu 810 includes the titles of the three major divisions of the travel guide. Upon selecting the first item in menu 810, i.e., 'Travel Guide to Paris", the next text menu 815 lists ten popular tourist attractions in Paris. The user is free to select any one of the ten, and in this example, the user selects the Eiffel Tower. This selection yields screen 820, which provides a textual description of the Eiffel Tower. Screen 820 also enables the user to select the "View" or "Pronounce" options. After selecting "View", the iPod screen displays a digital, full-color picture of the Eiffel Tower, as illustrated in screen 825. After selecting "Pronounce", the iPod will play back an audible pronunciation of the words "Eiffel Tower".

[0048] Referring to Figures 9 and 10, additional exemplary IRTs is shown.

In example 905, a study guide for the circulatory system has been downloaded onto the iPod. This study guide is likely to be useful to medical students who are taking a course relating to the circulatory system. Because the iPod is small and lightweight, it is much easier for the student to have the study guide accessible via the iPod than to carry the book of the same title. In example 910, a study guide for middle school-level geometry is shown.

[0049] Referring to Figure 11, examples of traditional reference titles 105 that are suitable for conversion to IRTs are shown. In example 915, a drug handbook, a reference manual for practicing physicians, is shown. Example 920 is a reference entitled "USMLE Review", which is a study guide for a standardized medical examination. Example 925 is an English/Spanish conversion reference for medical words and phrases, which is useful to many doctors who have patients that speak one or the other of these languages. Example 930 is entitled "Atlas of Histology", another medical reference. In this example, the reference includes a compact disk that includes image data to illustrate certain body structures in a pictorial fashion. Example 935 is a study guide for medical students facing standardized examinations.

[0050] Referring to Figures 12A and 12B, an exemplary educational flash card tool for children is shown. In this example, the flash cards are implemented on the iPod 415 as a set of images that show the user a question card followed by an answer card. The cards are graphically formatted to provide the user with a very fluid experience of clicking through a series of questions and answers by simulating physical flash cards. Referring to Figures 13A and 13B, another example of educational flash cards, this example being designed for medical students, is illustrated. The flash card implementation can be used for any appropriate subject matter and any target audience. In addition, in a preferred embodiment of the invention, custom thumbnail images of each flash card may be delivered by the MDA 410. By using a set of custom thumbnail images, text and reference numbers can be added to assist users in navigating the flash

cards. In another feature of the preferred embodiment of the invention, the MDA 410 enables a user to randomize the order of appearance of the flash cards by simply clicking a button in the MDA 410 while the iPod 415 is attached.

[0051] Referring to Figures 14A-14C and Figures 15A-15C, in a preferred embodiment of the invention, images included in an IRT file can be implemented to be scrollable and/or zoomable. In Figures 14A-14C, a map of a section of central North Carolina is shown at a selected level of resolution. In order to show the desired resolution, only a portion of the map may be displayed on the iPod 415 at any given time. Accordingly, the MDA 410 enables the user to scroll across the map, from the west to the east, while enabling the user to locate several important landmarks, such as cities, towns, and an airport. In Figures 15A-15C, a pictorial depiction of the brain is shown. In order to obtain a closer view of a user-selected region of the brain, the MDA 410 enables the user to zoom in on the selected region. The scrollability and zoomabϋity features may be implemented for any appropriate subject matter and any desired target audience.

[0052] An appendix to this specification is attached. The appendix includes software code written in the C programming language and used by the MDA 410; a software architecture for the MDA 410; a file format specification for files that are processed by the MDA; and an iPod Note Reader User Guide.

[0053] In a preferred embodiment of the invention, the platform of the iPod may be modified to provide a more user-friendly environment for accessing linked files of disparate data types that relate to a common subject. In particular, the

iPod uses an operating system that is run by software, i.e., a computer program. The iPod operating system software can be modified to include an ability to identify a reference title 105 to which a given iPod-ready file is related, independent of the data type of that iPod-ready file. For example, the iPod-ready file can include header information, and a portion of the header information can include a source reference identifier that uniquely links the file to the source reference title. The iPod operating system software can use the source reference identifiers to determine all files that have been downloaded to the iPod which are derived from the same source reference title 105. By modifying the iPod operating system software in the foregoing manner, the management of linked files related to a common subject is facilitated and enables simplified iPod navigation for users.

[0054] While the present invention has been described with respect to what is presently considered to be the preferred embodiment, it is to be understood that the invention is not limited to the disclosed embodiments. To the contrary, the invention is intended to cover various modifications and equivalent arrangements included within the spirit and scope of the appended claims. For example, although the preferred embodiment of the invention uses an iPod as the platform for the display and playback of linked data files having disparate data types, other hand-holdable devices for downloading and displaying or playing back information content may be used as a platform. The scope of the following claims is to be accorded the broadest interpretation so as to encompass all such modifications and equivalent structures and functions.

łPPENDIX

iPod Reference Title (IRT) 1 and Desktop Application (MDA) 2 General overview

• Currently, the media types that can be purchased and played on an Apple iPod include: songs, audiobooks, TV shows, short films, and music videos.

• Our mission is to use the current and emerging media capabilities of the Apple iPod (including audio and video playback, as well as the display of text and images) to create educational/edutainment "quick" reference guides and titles (i.e. what we call an iPod Reference Title, IRT).

Some examples of the application of IRTs that we are currently working on include:

- Travel guides

- Nature and field guides

- Restaurant and entertainment guides

- Medical and professional reference titles (e.g. drug guides)

Higher education supplementary media (e.g. flashcards, quizzes and study guides)

Professional training guides

Our business model is to license existing multimedia content from publishers, convert the media assets to iPod-ready files using a set of scripts and manual procedures. The IRT (see below) will be purchased (downloaded or on CD) and the consumer will use our freely available Desktop Application (what we call MDA, in essence, the content management software) to install the title on to the iPod. (for more info, see support_docs/Modality_exec_sum.pdf)

The resulting product (the IRT) is a collection of media assets that are interlinked using the Notes (found under Extras in the iPod menu) feature of the iPod.

Basic use of IRTs:

- User navigates to an item of interest and selects it

- User is presented with a text description, links to other note files, and links to audio files.

1 We have referred to this in the past at the 'glossary application' or 'quick reference guide' or simply 'title'

2 Modality is the 'working' name of the LLC; MDA: Modality Desktop Application

• The audio (the song) has an image associated with it (the album art) which is displayed during audio playback.

• Selecting the audio while its playing (or paused) will allow the user to view the image in higher resolution.

In our current implementation of the IRT (as in the SylviusVG, Brain reference) the IRT comprises a set of media assets (in the case of Sylvius, its a notes folder and a set of mp3 files; the mp3 files have an image embedded) that the user manually 'installs' on their iPod. The notes are added to the iPods "Notes" folder, the mp3s are added to the user's iTunes library. In all future creation of IRTs, the disparate media assets will be unified and delivered as an .mtp file.(.mtp = modality title package, see below)

The Desktop application (MDA) manages and installs the IRT on the iPod. It supplants the manual movement of folders, as well as the dependence on iTunes to add audio, video and image files (iTunes is very kludgey in handling the various media types).

MDA reads only one file type, a .mtp file (modality title package), .mtp is our creation and represents a new digital file type (e.g. .mp3, .doc, .mov) to deliver the IRT. It concatenates all of the title's assets (video, audio, text, pdf files, images) into a single file, .mtp can only be read by our content management software, MDA.

Basic operation of the MDA:

The user connects their iPod to their PC (MDA is cross platform, versions for both Mac and Win).

iPod is recognized by the PC and the MDA is launched.

The user can install an IRT (one that they have purchased via download or on CD). Alternatively, they can uninstall an IRT as well. To install an IRT, the user simply loads a .mtp file and selects 'install.'

The MDA reads the .mtp file and installs all of its embedded media assets on the connected iPod. MDA does this by writing directly to the set of files commonly referred to as the iTunes database files and to the Notes folder on the iPod.

- Once MDA completes installation, user ejects iPod.

IRT: Additional Notes

• IRT concept is based on the built-in Notes feature of the iPod- the notes are all text files- currently there is no way to embed other media, e.g. images;

• Notes are size-(4K per note) and number-limited (1000 total notes)

• iPod Notes have limited HTML tagging capabilities- simple links to other notes and to audio (see ipodnotesreader.pdf in the Supporting docs/Apple folder)

IRTs work on 4th generation (photo) and 5th generation (video) iPods as well as the iPod nano- i.e. all iPods with a color display.

IRTs do not 'hack' the iPod Software

IRTs are not 'executable' programs that run under an OS. All code is simple HTML recognized by the iPod in the form of xml text files (for example see support_docs/IRT/IRT_note_examp.pdf)

• We completed our first IRT (brain glossary) in early September 2005 and released it first to Duke University pre-medical students no later than September 15, 2005.

We first demonstrated the IRT to Apple representatives in November 2005.

• In our opinion, what is the innovation in the currently released version of an IRT (e.g. our brain glossary) ?

- using the Notes links to mp3s and the embedded album art of a song as a means of providing an audio pronunciation (or other educational audio information) of the item and a descriptive image of the item

- the innovation is mainly conceptual and applied: how the built-in capabilities of the iPod Notes were used to produce a multimedia reference tool, i.e. use for education or training and not for music.

- example- 'typical' iPod use: song displaying the album art; our IRT use: audio file of an audio recording of a bird call displaying an image of the species

- the scripts used to automate the creation of the IRT. These comprise a set of PERL scripts used to create the XML files and Notes links, as well as to to embed images into mp3 files.

Our initial assessment of what others have done: [not sure when these groups actually debuted their products. We were not aware of any application that linked text, audio and album art/image until after ours was in service (at Duke), roughly Sept 15, 2005]

Talkingpanda has released a few Notes-based titles, including a bar tenders guide (drink recipes) and language learning titles (notes and audio)- as far as we know they have not linked up images to any of this

Helmes Innovations- it appears that this group has produced some products with very similar (perhaps identical) functionality. On their website they are claiming for each the 4 titles (bar tending guides, beauty guide, workout guide) PATENT PENDING. http://www.helmesinnovations.com/products.html

The concept of using album art as a means of linking text notes to images (i.e. a workaround for the lack of direct support for this on the iPod) was noted on a blog posting:

"While it is currently impossible to link to a photo from within a note on an iPod photo, I have seen an interesting work-around. Some people are creating a blank audio file and adding the photo as the album art, You can then link to the dummy audio file which will show the phot you want."

Posted by: arb on June 13, 2005 at 06:20 PM httD://www.makezine.com/bloα/archive/2005/06/make ebooks for l.html

3 Currently, only songs can be linked directly to Notes.

Our current version of the IRT 4 is certainly more innovative and to the best of our knowledge, no one has anything like it. As compared to our released version of an IRT (e.g. brain glossary), IRT-n is characterized by a couple of key features:

the IRT-n is created using a set of scripts just like the IRT but once the creation/conversion of media assets has been done, the IRT-n assets are converted to a .mtp file. So a single .mtp file represents the total content and assets of an IRT-n.

- A key difference exists between the scripts that generate the IRT and the IRT- n .mtp file. Instead of using iTunes to 'install' audio and image files on the

3 One of the key elements of our discussion with Apple next week will be in encouraging them to expand the ability of Notes to include linking directly to Photos, videos as well as implementing additional behaviors that will allow us to create more robust IRTs. Apple has indicated that these changes are easy to implement and they are willing to make them.

4 1 will use the abbreviation IRT-n to indicate the current, non-published version

iPod, our IRT-n scripts utilize the many different image formats to create custom thumbnail and full size images- currently not possible using iTunes or any other software. This is not trivial because it allows us create things like thumbnail keys for icons and symbols, low and high res images for different displays or iPod models, etc. the IRT-n can only be installed and utilized by the MDA. Unlike the 'exposed' assets of the current IRT, the IRT-n assets would not be available prior to installation using the MDA.

IRT-n and MDA system affords opportunities for DRM (digital rights management). The .mtp file could contain some form of copy protection or encryption read only by the MDA.

MDA: Additional Notes

The MDA provides integration with the iPod Database formats (for more information about the iTunesDB files see http://ipodlinux.org/ltunesdb#iTunesDB_file) allowing 1 -click installation and management of disparate media types that heretofore required multiple applications to manage and manual copying of files to specific locations on the iPod.

Mac and Windows compatible

The MDA architecture has been specified in detail (for spec see support_docs/MDA/MDA_architect.pdf) and nearly all aspects of the program are functioning currently.

Currently, there is no user interface.

Code is written in C (files in the support_docs/MDA/ folder with an _c are pdf files of the code)

The .mtp file type has been spec'ed (see support_docs/MDA/MDA_file_spec.pdf) and the MDA can now read and write this file type.

Summary of key innovations:

Concept of utilizing Notes and its basic linking capabilities, and the embedded image property of mp3 files to create educational/edutainment reference titles (IRTs).

Creation of a novel file type containing all of the media assets of the IRT.

Creation of a program (MDA) to create, manage and install IRTs on the iPod.

Modality Desktop Application (MDA) Proposed Architecture and Behavior

iPod Filesystem Layout

MDA will add a folder under iPod_Control that will store Modality-related content. MDA will modify ArtworkDB, ϊTunesDB, and Photo Database, appending entries for relevant Modality title media assets synched to the iPod. MDA will reference its own ithmb (concatenated 16-bit RGB565) image streams and music folders.

CD iPod_Control

CD Artwork / Contains album artwork data ϋ ArtworkDB / Binary file describing artwork data stored in ithmb files Ip * .ithmb / 16-bit RGB565 binary stream

CD Music / Contains folders for audio and video

CD FOO CD Fnn

CD iTunes

Bl iTunesDB / Binary file describing audio and video files stored in Music CD Modality

Bl Preferences / File containing MDA settings CD Music / Contains folders for Modality audio and video CD Artwork / Contains Modality album artwork ithmb files □ Photos / Contains Modality photo ithmb files

CD Notes CD Photos

Bi Photo Database / Binary file describing photo data stored in ithmb files

CD Thumbs j| * .ithmb / 16-bit RGB565 binary stream

Modality Title Installation Sequence

1. Sanity checks

1. Check versions (iTunes, iPod)

2. Check for iTunesLock (transient file created by iTunes when writing to DB files)

3. Check for sufficient space (number of notes and disk capacity)

2. Open /iPod_Control/Modality/Lock file to prevent iTunes from ejecting

3. Install audio and video

1. Open write file handle to /iTunes_Control/Modality/iTunesDB

2. Open read file handle /iTunes_Control/iTunes/iTunesDB

3. Copy to /iTunes_Control/Modality/iTunesDB

1. Check if entry exists for each Modality audio/video file

2. If entry exists, check that audio file is present at location=":..."

3. Add new entries as needed

4. If entry needed, copy file to /iTunes_Control/Modality/Music/

4. Finish writing to /iTunes_Control/Modality/iTunesDB

4. Install album artwork

1. Open write file handle to /iTunes_Control/Moda!ity/ArtworkDB

2. Open read file handle /iTunes_Control/Artwork/ArtworkDB

3. Copy to /iTunes_Control/Modality/ArtworkDB

4. Check if entry exists for each artwork file

5. Add new entries as needed, copying art to /iPod_Control/Modality/Artwork/

6. Finish writing to /iPod_Control/Modality/ArtworkDB

5. Install photos

1. Open write file handle to /iTunes_Control/Modality/Photo Database

2. Open read file handle Photos/Photo Database

3. Copy to /iTunes_Control/Modality/Photo Database

4. Check if entry exists for each photo file

5. Add new entries as needed, copying images to /iPod_Control/Photos/

6. Add Album List entry(ies) to Photo Database

7. Finish writing to /iPod_Control/Modality/Photo Database

6. If all OK:

1. Move new iTunesDB to iTunes/iTunesDB

2. Move new ArtworkDB to iPod_Control/Artwork

3. Move new Photo Database to Photos/Photo Database

4. Update Modality/Preferences to list installed titles

5. Take MD5 checksum of DB files, save to Preferences, and check when ejecting iPod via MDA to ensure updates have not been overwritten by iTunes.

7. OK to eject. Eject via MDA to release lock by closing the file handle to Lock.

Development Timeline

Parsers and writers Fri 1.27 iTunesDB parser and writer

ArtworkDB parser and writer

Photo Database parser and writer

RGB565 writer

Photoshop can create 16-bit R5G6B5 bitmaps, need code to byte-swap to G3R5B5G3 as well as interlaced YUV and 90° rotation.

File format Wed 2.1 Need to decide what to handle at publish time and what MDA should handle at run time (mostly image-formatting-related).

File format reader/writer Tue 2.7

GUIs Fri 2.24 Windows first?

Modality title management Wed 3.1 e.g. "Add to Library"

Registry and plist (file association) Mon 3.6

Services (launch when iPod attached) Mon 3.13

Sanity checks Wed 3.15

Installers Fri 3.24

iPod Note Reader User Guide

April 25, 2003 iPod 2.0 software brings exciting new features to your iPod, including a Note Reader that displays text files that are stored in the Notes folder on the iPod.

The Note Reader also displays the folder hierarchy in the Notes folder, allowing you to organize your notes.

The size of any single note is limited to 4kb, any text beyond 4kb is truncated.

The Note Reader supports up to a thousand notes, if there are more than a thousand notes in the Notes folder only the first one thousand will be loaded.

Notes are cached. If a note has been read into the cache, the hard disk can display it without spinning up the iPod's hard disk. Up to 64Kb of notes can be read into the cache at one time. Once the 64Kb cache limit is exceeded, the oldest notes are discarded as new information is read in.

Tags

The Note Reader supports some basic HTML style tags. These tags are not case sensitive.

Force a paragraph break by including <BR> or <P> and </P>.

By default, notes are listed using the file name unless you specify a name with the Title tag.

<TITLE>New Title</TITLE>

This is useful with .link files, described below. It can also be used in the Preferences file, also described below.

The <INSTRUCTIONS> tag is unique in that it causes the entire contents of the note to be replaced by short instructions on using the Note Reader, and the file name to be listed as "Instructions", both in the currently selected language.

Links To Files

One note can link to another note. A link looks like this:

<A HREF="note fiIe">Link to another note</A>

Links are underlined when displayed on the iPod. By pressing the select button the link is followed. If more than one link is visible at a time, only one will be underlined. Use the scroll wheel to move between multiple links.

Links can specify a file with an absolute or a relative reference. Absolute references always start in the Notes folder. Relative references start in the folder the original note is in.

Absolute links look like this:

<A HREF="file:/ / /note file">Link to another note</ A>

<A HREF="file:/ / /folder/note file">Link to another note</ A>

<A HREF="/ note file">Link to another note</ A>

<A HREF=" /folder /note file">Link to another note</A>

Relative links look like this:

<A HREF="file:/ /note file">Link to another note</A>

<A HREF="file:/ /folder/note file">Link to another note</A>

<A HREF="note file">Link to another note</A>

<A HREF="folder/note file">Link to another note</A>

Folder can be a link destination.

The top level of the Notes folder can not be link destination.

A file outside the Notes folder also can not be a link destination.

A link cannot refer to a .link file, described below.

File names in links are not case sensitive.

Links are checked to make sure they specify a file that actually exists. Dead links are listed in the <ERRORS> tag, described below.

.Link Files

If a file name ends in .link and contains a link, when the user selects the .link file they immediately follow the link to the specified file or song.

For instance, if the file named Filel.link contains the text: <A HREF="File2">The link</ A>

When the user selects Filel.link File2 will be presented and the contents of Filel.link will not be shown.

■Linx Files

If a file name ends in Jinx and contains links, it is presented as if it was a folder containing .link files, one for each link.

Regular items in folders are listed in alphabetical order. Links listed in .linx files are listed in the order they appear in the .linx file and are not alphabetized.

If a file named Main.linx exists in the top level of the Notes folder, it is used for the Note Reader main screen, replacing the actual contents of the Notes folder. If the Main.linx file has a <TITLE> tag, it overrides the <TITLE> tag in the Preferences file, if one exists.

Path Delimiters

When linking to a file in another folder, the folders and file names in the path must be delimited with either a forward slash '/', backslash y \', or colon ':' as in the below example:

Folder /file Folder \ file Folderfile

The three path delimiters are equivalent.

Note that all three path delimiters are illegal characters for FAT file names, and that colons are illegal characters for HFS+ file names.

If a folder name itself contains these special characters they must be escaped with a backslash. Example: A link to a file named "Meeting 10/12/02" would be represented this way: <A HREF="Meeting 10\ /12\ /02">Link to another note</A>

If the first or last character of a file or folder name is a slash or backslash, even with escapes it could be ambiguous which characters are part of the file or folder name, and which are path delimiters. In this case you should use a colon as a path delimiter.

For example, a link to a folder called "Folder \" would be represented this way: • <A HREF="Folder\ \:note file">Link to another note</A>

You cannot specify a folder above the starting folder. For a link in a sub folder to specify a file in a folder above it, it must use an absolute specification.

Full path names must fit in 255 characters. More specifically, they must fit in 255 UTF8 Unicode bytes, and in 510 UTF16 Unicode bytes. Some characters expand to more than one UTF8 byte or more than two UTF16 bytes, so some paths may not fit even though they would appear to. See the Unicode specification for details.

Files whose full paths are too long are not loaded, and no error is reported. Note that this applies to other iPod applications as well, such as Contacts and Calendars.

Links To Songs

Linking to a song is similar to other links:

<A HREF="song=My Way">Link to My Way</ A>

If there are multiple songs named My Way, the user cannot select among using this link format.

For more control a you can use filters as specified below:

<A HREF="ipod:music?playlist=Road Music">Link to Roadie</ A>

<A HREF="ipod:music?genre=triphop">Link to a genre</A>

<A HREF="ipod:music?artist=Todd Rundgren">Link to FZ</ A>

<A HREF="iρod:music?composer=Beethoven">Link to Beethoven</ A>

<A HREF="ipod:music?album=The Wall">Link to Pink</A>

<A HREF="ipod:music?song=Althea">Link to Althea</ A>

Filters can be combined to create a temporary playlist of songs that match all filters. <A HREF="ipod:music?genre=rock&artist=Brian Eno">Combo</A>

By default, the Now Playing screen comes up when the user selects a music link. This can be specified for all notes, or for a single note, with a preference setting. See the Preferences section below,

You can override this for a single link with the Now Playing tag.

<A HREF="ipod:music?song=Althea&NowPlaying=false">Link to Althea</A>

If a play list is selected, the only other filter you can use is a song. You can only have one selection for each filter type.

All matching is case insensitive, but otherwise must match exactly. Wild card characters are not supported.

Links are checked for formatting errors but links are not checked for validity to see if the song actually exists. Errors are listed in the <ERRORS> tag. See Preferences and the Errors tag, described below.

Encoding

By default all note files are considered to be encoded in Latinl, unless the iPod language is set to Japanese, Korean, or traditional or simplified Chinese, in which case all note files are assumed to be in that encoding.

A note file can be tagged as having a different encoding. See the example below. <?xml encoding="MacJaρanese"?>

The following encodings are supported: Latinl, MacRoman, Macjapanese, Korean, simplified Chinese, traditional Chinese, UTF8 Unicode and UTF16 Unicode.

The following encoding names are supported:

For Latinl: iso-8859-1, Latin-1.

For MacRoman: x-Mac-Roman, Mac, Macintosh.

For Macjapanese: x-Mac-Japanese, Mac-Japanese, Macjapanese, Shift-JIS, Shift_JIS.

For traditional Chinese: x-Mac-Chinesetrad, Mac-Chinesetrad , BIG5, CN-BIG5.

For simplified Chinese: x-Mac-Chinesesimp, Mac-Chinesesimp, EUC-CN.

For Korean: x-Mac-Korean, Mac-Korean, EUC-KR.

For UTF8 Unicode: UTF8, UTF-8.

For UTF16 Unicode: UTF16, UTF-16, UCS2, Unicode.

(Each line lists multiple names for the same encoding, not separate encodings.)

Some of these encodings are not actually identical, but they are treated as if they were; for instance EUC-CN is not precisely the same as simplified MacChinese, but it is rendered as simplified MacChinese on the iPod. This will work for almost all characters.

UTF8 and UTF16 Unicode can also be specified with a Byte Order Mark (BOM). Byte swapped (little endian) UTF16 files are supported, but only with a BOM but not with an encoding tag. Note that TextEdit adds a BOM when saving UTF16 files, but not when saving UTF8 files. BBEdit 7.0.3 will display the file encoding, whether or not it has a BOM, and has options to save it with or without a BOM.

The only way to display multiple encodings in the same note is to use Unicode.

If the encoding tag and the BOM disagree, the encoding tag overrides the BOM. Encoding tags are not case sensitive.

The encoding tag must be placed at the top of a file, before any non-ASCII text, otherwise, a null char in non-ASCII text may prevent the parser from getting to the encoding tag. Only one encoding tag is allowed per file.

Do not put null characters in encodings that use null as a terminator such as Latinl, MacRoman, and UTF8 or else the text will be truncated at the null character.

Preferences

Global preferences can be specified by including a file called Preferences in the top level of the

Notes folder. Preferences are written in XML format.

Local preferences can be specified for any note file by including XML preference tags within the file that overrides. any equivalent global preference for that note.

If multiple tags for the same preference in a single note are found only the last preference parsed will be used for the entire note.

Preferences for any note can be displayed with the <SHOWPREFERENCES> tag. If any local preference overrides a global preference, the local value is displayed, otherwise the global value is displayed.

Preferences are set with these XML incantations: <meta name="LineWrap" content="true"> <meta name="ShowBodyOnly" content="true"> <meta name="HideAUTags" content="true"> <meta name="NowPlaying" content="true"> <meta name="NotesOnly" content="true">

One or several preferences can be set at once, and not all have to be specified. Preference values can only be "true" or "false." All preferences default to false except for NowPlaying, which defaults to true.

If LineWrap is set to false, LF and CR in notes are respected. Mac, PC, and Unix style returns are treated equally. If LineWrap is set to true, LF and CR are ignored, and only <P> and <BR> cause new lines.

ShowBodyOnly will only display the portion of the note within <BODY> </BODY> tags, if present. If <BODY> tags are not present, the entire note is displayed.

HideAllTags removes all o style tags before displaying the note, including unrecognized tags. NowPlaying controls whether the Now Playing screen appears after selecting a link to a song.

NotesOnly, also called Museum Mode, causes the iPod to boot into the Note Reader screen, and prevents the user from exiting the Note Reader. This allows the creation of custom or restricted user interface. NotesOnly can only be set in the global preferences file, not in individual note files.

The title of the main Note Reader screen can be set by specifying a <TITLE> tag in the global preferences file.

Preferences, like all tags, are not case sensitive. Errors

To save time manually verifying your note files, the Note Reader automatically checks each note for errors.

Any note containing the <ERRORS> tag will have its entire contents replaced by errors found while parsing the note files.

Only one note with an <ERRORS> tag is required to see all of the errors in all note files.

Various types of errors are reported, including badly formatted tags and dead links that specify a non-existent file or song.

Known Issues

A link to the Notes folder cannot be created.

While displaying the list view (list of files and folders), the hard drive sometimes does not spin down.

Music filters cannot contain an ampersand. For instance, these links do not work:

<A HREF="iρod:music?genre=country&western">Link to genre</ A> <A HREF="ipod:music?artist=hall&oates">Link to artist</ A>

When the preference HideAllTags is true, some HTML comments are not properly hidden.

Modality File Format Specification mhbd

mhsd

Types: 1 = title, 2 = notes, 3 = audio/video, 4 = artwork, 5 = photos, 6 = PDFs, 7 = binary data

Title mhsd has 3 string mhod (title [2], genre [3], artlst[4]) and 1 binary mhod [10] ("book cover" jpeg image)

Note mhsd contains mhin

Audio/video mhsd contains mhit

Artwork mhsd contains mhii and mhba

Photo mhsd contains mhii

PDF mhsd contains mhdp

Binary mhsd contains loads of binary (at end of file)

mhin (note Item)

Contains 1 or 2 mhod and nested mhin if type= =directory

mhba (photo album)

Field Byte offset Byte length Value Comments

Tag 0 4 mhba

Header length 4 4 64 size of tag header

Total length 8 4 mhod count 16 4 1 1; title [2] nrihod number of images 20 4

Rest of header is 0-padded

Title string-type mhod, then list of mhii IDs in desired order (byte length s 4 * n_entries) mhdp (pdf entry)

mhod

Types:

Strings: 0 = filename, 1 = note text, 2 = title, 3 = artist, 4 = genre, 5 file type

Binary: 10 = image, 11 = audio, 12 = video, 13 = pdf

Sample

(mhbd) Database

Tag

Header length

Title total length - for quick ref to check space available?

File format version

Title ID (e.g. 0001, unique for each Modality title)

Title revision (e.g. 0001, 0002, etc.)

Publish date

ISBN?

<paddiπg>

(mhsd) Title Info

Tag

Header length

Total length

Type child count

<padding>

(mhod) String container (for title name, e.g. "Western Medicinal Plants")

Tag

Header length

Total length

Type

<padding>

String container body (not padded) Data (string - always UTF-16??) (mhod) String container (for artist/publisher, e.g. "Modality Learning")

(mhod) String container (for genre, e.g. "Books & Spoken") (mhod) Binary container (title image/"book cover")

Tag

Header (ength

Total length

Type

Width (if image)

Height (if Image)

(iPod doesn't appear to need audio/video info like bit rate, milliseconds, etc.)

Byte offset to binary data

<padding>

(mhsd) Notes Tag

Header length

Total length

Type child (mhin) count

<paddiπg>

(mhin) Note

Tag

Header length

Total length

Type (note = 0 or directory = number of entries)

Number of containers (eg. mhod)

<padding>

(mhod) String container (for file/directory name)

(mhod) String container (present in type==note, =note text)

If type=directory, nested Note entries are here Read number of entries (=type attribute)

(mhsd) Audio/Video

Tag

Header length

Total length

Type child (mhit) count

<padding>

(mhit) Audio/Video

Tag

Header length

Total length

ID?

Movie or song?

Media type - see iTunesDB

Artwork count??

<padding>

(mhod) String container for Title (type 2)

(mhod) String container for Filetype (e.g, "MPEG Audio File")

(mhod) Binary container for file data

(mhsd) Artwork/Photos

Tag

Header length

Total length

Type child (mhba and mhii) count

<padding>

(mhba) Photo Album

Tag

Header length

Total length

Number of entries

List of IDs in desired order (byte length = 4 * n_entries)

<padding>

(mhod) String container for Title (type 2)

(mhil) Artwork/Photo

Tag

Header length

Total length

ID (if artwork, corresponds to audio ID)

MHFI (image format) Type - see artworkdb.c

<padding>

(mhod) Binary container for image data

(mhsd) PDFs

Tag

Header length

Total length

Type child (mhdp) count

<padding>

(mhdp) PDF

Tag

Header length Total length mhod count <padding>

(mhod) String container (for filename - type 0)

(mhod) Binary container for image data

(mhsd) Binary Data MHSD (byte offsets calculated from this point) Concatenated binary data for all files

<?xml encoding="UTF8"?>

Angular gyrus

<a href="ipod:music?song=Angular gyrus&NowPlaying=true">View</a> I <a href="ipod:rausic?song=Angu

Gyral structure of the inferior parietal lobule that surrounds the termination of the superior t

Location: inferior parietal lobule

Function: involved in processing language, spatial orientation, and semantic representation

About this image:

Photographic image of a lateral view of the left hemisphere of the human brain.

See Also:

<a href="Parietal lobe">Parietal lobe</a>

<a href="Wernicke's area">Werniclce' s area</a>

<a href="Superior temporal sulcua">Superior temporal sulcus</a>

<a href="Brodmann' s area 39">Brodmann's area 39</a>

<a href="lnferior parietal lobule">lnferior parietal lobule</a>

#i£ndef IPODIO-H #define IPODIO H

// flags

#define IPOD_GEN4 1

#define IPOD_NANO 2

#define IPODJ3EN5 4

#define STRING_REVERSE 1

#define STRING_UTF16 2

#define STRINGJTOUTFB 4

#define UINT NOREiVERSE 8

typedef unsigned long long int uint64; typedef unsigned long int uint32; typedef unsigned short int uintlβ; typedef unsigned char uintβ;

uinta ipodio_buf [512] ; uintlβ ipodio_wbuf[256]; uinta big_eπdian;

// byte offset and byte size typedef struct

{ uint32 offset; uint32 length; uint32 offset_count; uint32 count; uint32 offset_entries; uint32 type; /* the mhsd type */ > state;

uint64 ipodio_read_uintn(FILE *fh, const uint32" nbytes, const uint32 flag); uint64 ipodio_read_uint64 (PILE *fh, const uint32 flag); uint32 ipodio~read_uint32(FILE *fh, const uint32 flag); uintlβ ipodio_read_uintl6(PILE *fh, const uint32 flag); uintS ipodio_read_uint8(FILE *fh, const uint32 flag); uint32 ipodio_read_string(FlLE *fh, const uint32 nbytes, const uint32. flag); uint32 ipodio_set_utf16(uint8 *dest, uint32 offset, void *value, uint32 nbytes); uint32 ipodio_set_uintn(uint8 *dest, uint32 offset, void *value, uint32 nbytes);

#endif

#include <stdlib.h> #include <stdio.h> #include <string.h> #include "ipodio.h"

#ifdef cplusplus extern "C" { #endif

uint64 ipodio_read_uintn(PILE *fh, const uint32 nbytes, const uint32 flag)

{ uint32 fact = 0, i; uint64 u = 0; if (fread(ipodio_buf , 1, nbytes, fh) != nbytes) { printf( "Read error\n"); exit(EXIT_FAILURE) ; } if (flag & UINT_NOREVERSE) { // 0002 = 2 fact = 8 * (nbytes - 1); for(i - 0; i < nbytes; i++) { u += ipodio_buf[i] « fact; if(i < nbytes - 1) { fact -= 8; } } } else { // 0200 = 2 for(i = 0; i < nbytes; i++) { u += ipodiojbuf[i] « fact; if(i < nbytes - 1) { fact += 8; } } } return(u); } uint64 xpodio__read_uint64 (FILE ' *fh, const uint32 flag) { // read 8 bytes return( ipodio_read_uintn( fh, 8 , flag) ) ; } uint32 ipodio_read_uint32(FILE *fh, const uint32 flag) { // read 4 bytes return ( (uint32)ipodio_read_uintn(fh, 4, flag)); } uintlδ ipodio__read__uintl6(FILE *fh, const uint32 flag) { // read 2 bytes return ( (uintl6)ipodio_read_uintn(fh, 2, flag)); } uintδ ipodio_read_uint8(PILE *fh, const uint32 flag) { // read 1 byte

return ( (uintδ ) fgetc ( fh) ) ;

uint32 ipodio_read_string(FILE *fh, const uint32 nbytes, const uint32 flag)

{ uint8 tmp, *buf; uint32 i; if (flag & STRINGJUTF16) { // read UTF-16 buf = (uintδ * ) ipodio_wbuf; > else { buf = ipodio_buf; > fread(buf, 1, nbytes, fh); if (flag & STRING_OTF16) { if(flag & STRING_TOUTF8 ) { // collapse to 1 byte (remove zeros) for(i = 0; i < nbytes; i += 2) { ipodio_buf[(int)(i / 2)] = buf[i];

> ipodio_buf [ (int)(nbytes / 2)] = '\0'; return(O) ; >

// swap the bytes for(i = 0; i < nbytes; i += 2) { tmp = buf [ i] ; buf[i] = buf[i + .1] ; buf[i + 1J = tmp; > } if (flag & STRING-REVERSE) { // reverse for(i = 0; i < (int)nbytes/2; i++) { tmp = buf[i]; buffi] = buf[nbytes - i - I]; buf[nbytes - i - 1] = tmp; } } buf[nbytes] = '\0'; return(0 ) ;

*

* set iPod-formatted UTF-16 string at dest + offset * uint32 ipodio_set_ut£16(uint8 *dest, uint32 offset, void *value, uint32 nbytes) { uint32 i; for(i = 0; i < nbytes * 2; i += 2) { ipodio_buf [i] = *(uint8 *) (value + i/2 ) ;

ipodio_buf[i + 1] = '\0'; } rhemcpy(dest + offset, ipodio_buf, nbytes * 2); return(O) ;

*

* set iPod-formatted uint of size nbytes at dest + offset

* uint32 ipodio_set_uintn(uint8 *dest, uint32 offset, void *value, uint32 nbytes) { void *ptr; uintδ buf[8], i, tmp; if (big_endian) { for(i = 0; i < nbytes; i++) {

*(buf + i) = *(uintδ *) (value + nbytes - i - 1);

} ptr = buf; } else { ptr = value; } memcpy(dest + offset, ptr, nbytes); return(O) ;

#ifdef cplusplus extern "C" } #endif

/* gcc itunesdb.c ipodio.c -o itunesdb_reader don't appear necessary:

- sample rate and bit rate fields necessary?

- CBR, __3PM, bytes, millisecond necessary?

- artwork size in iTunesDB?

*/

#include <stdlib.h> #include <stdio.h> #include <string.h> #include "ipodio.h"

#ifdef cplusplus extern "C" { #endif

#define BYγES_MHIT 0xf4 #define BYTES_MHOD 0x18

// default values struct

{ uint32 sample_rate; } defaults ;

// needs vars for struct

{ uint64 dbid; uint32 unigueid; uint32 new_entries; uint32 mhod_count; uint32 mhod52_count; uint32 mhit__bytes ; uint32 mhip_bytes f uint32 ipod_type; } status; typedef struct { uint32 bytes; uint32 milliseconds; uint32 bit_rate; uint32 sample_rate; uint32 artwork_count; uint32 artwork_bytes; uint32 media_type? char ' *title; char *location; char *album;

char artist; char *genre; char *filetype; void ♦next;

} track;

// mhit and mhip containers fcypedef struct

{ uint8 *object; uint8 mhod_count ; uint32 length; > mhi; mhi *mhit_l±st[1024]; mhi *mhip_list[1024]; uint32 mhsd_σount = 0; uint32 mhod_count = 0; state mhbd_stafce; state mhsd_stafce [ 3 ] ; // these may need map to mhsd type 2 and 3 (ie. might be reversed depending state mhyp_state[3]; // these may be mhlt or mhyp

Estate mhod_state[10] ; // points to playlist mhod (type 52) for adding to index list

*

* read a data object (MHOD) * uint32 itunesdb_read_mhod(FILE *fh)

{ uint32 i, len, tot, nbytes, k, j, type, fpos; i = ipodio_read_string(fh, 4, 0); if (memcmp(iρodio_buf, "mhod", 4) != 0) { printf("Not a valid iTunesDB file\n" ) ; exit ( EXrT_FAILDRB ) ; }

// header .length len = i = ipodio read_uint32(fh, 0);

// total length tot = i = ipodio_read_uint32(fh, 0);

// type i = ipodio_raad_uint32(fh, 0 ) ; if(i < 15 ) { // mhod type 0 - 14 (string type)

// unkl i = ipodio_read_uint32(fh, 0);

// unk2

i = ipodio_read_uint32(fh, 0);

// position i = ipodio_read_uint32(fh, 0);

// string length nbytes =.i = ipodio_read_uint32(fh, 0);

// unk i = ipodio_read_uint32(fh, 0);

// unk4 i = ipodio_read_uint32(fh, 0); ipodio_read_strin.g(fh, nbytes, STRINGJQTF16 | STRING_TOUTF8) ; // string mhod (type < 15) are not 0-padded

} else if (i == 100 SS tot == 0x2C) { // mhod type 100 where <mhip><mhod/></mhip> only fseek(fh, 8, SEEK_CUR) ;

// position i = ipodio_read_uint32(fh, 0); fseek(fh, 16, SEEK-CUR); } else if(i == 52) { state * st; fpos = ftell(fh); • fseek(fh, 8, SEEK-CUR);

// index type type = i = ipodio_read_uint32(fh, 0);

// count k = i = ipodio_read_uint32(fh, 0); st = S (mhod_S"tate[mhod_count] ) ; mhod_count++; st->offset = fpos - 8; st->length = tot; st->offset_count = fpos + 12; st->count = k; fseek(fh, 40, SEEK_CUR); for{j = 0; j < k; j++) { i = ipodio_read_uint32(fh, 0);

}

// save a byte offset, ref to this point for adding new files st->offset_entries = ftell(fh);

} else {

// unsupported mhod • fseek(fh, tot - 16, SEEK_CUR);

} return (0) ;

*

* read a playlist item (MHIP)

uint32 itunesdb_read_mhip(FILE *fh) { uint32 i, len, tot, n_mhod, fpos; i = ipodio_read_string(fh, 4, 0); if(memcmp{ipodio_buf, "rohip", 4) != 0) { printf("Not a valid iTunesDB fileW); exit(EXIT_FAILURE); }

// header length len = i = ipodio_read_uint32(fh, 0);

// total length tot = i = ipodio_read_uint32(fh, 0);

// MHOD count n_mhod = i = iρodio_read_uint32 ( fh, 0 ) ;

// podcast grouping i = ipodio_read_uint32 ( fh, 0 ) ;

// group id i = ipodio_read_uint32(fh, 0);

// track id i = ipodio_read_uint32(fh, 0);

// timestamp i = ipodio_read_uint32(fh, 0);

// podcast grouping reference i = ipodio_read_uint32(fh, 0);

// the rest of the header is 0-padded fseek(fh, len - 36, SEEK-CUR); for( i = 0; i < π_mhod; i++) { itunesdb__read_mhod( fh) ; } return(O) ;

*

* read a playlist (MHYP)

uint32 itunesdb_read_mhyp(FILE *fh)

{

// want state_mhyp. offset to be at insertion point uint32 i, len, tot, fpos, n._mhod, n_mhip, j; 3tate * st; st = &(mhyp_state[mhsd_count] ); fpos = ftell(fh); i = ipodio_read_string(fh, 4, 0); if (memcmp(ipodio_buf, "τnhyp" , 4) != 0) { printf("Not a valid iTunesDB £ile\n"); exit(EXIT_FAILURE) ; }

// header length len = i = ipodio_read_uint32(£h, 0); st->offset = fpos + 8;

// total length tot = i = ipodio_read_uint32(fh, 0); st->length = tot;

// no. MHOD n_mhod = i = ipodio_read_uint32 (fh, 0); st->o£fset_count — fpos + 16; // save number of playlist objects (mhip) - but should just be

// no. MHIP n_mhip = i = ipodio_read_uint32 (fh, 0); st->count = n_mhip;

// is master playlist? i = ipodio_read_uint32(fh, 0); fseek(fh, len - 24, SEEK_CUR) ;

// should be into playlist body now for(i = Of i < n_mhod; i++) { itunesdb_read_mhod( fh) ; } £or(i = 0; i < n_mhip; i++) { itunesdb_read_mhip( fh) ; }

// jump to the end of the playlist item fseek(fh, fpos + tot, SEEK_SET);

// save the mhip insertion byte offset st->offset_entries = fpos + tot;

}

/****

*

* read a playlist list (MHLP) * uint32 itunesdb_read_mhlp(FILE *fh) { uint32 i, len; i = ipodio_read_string(fh, 4, 0); if (memcmp(ipodio_buf, "mhlp" , 4) I= 0) { printf("Not a valid iTunesDB file\n"); exit(EXIT_PAILURE) ; >

// header length len = i = ipodio_read_uint32(fh, 0);

// playlist count i = ipodio_read_uint32(fh, 0); fseek(fh, len - 12, SEEK_CUR) ;

// we only care about the first one - Library itunesdb_read_mhyp( fh) ; return( 0) ;

*

* read a track item (MHIT) * uint32 itunesdb_read_mhit(FILE *fh)

{ uint32 i, len, n_mhod, fpos; uintlβ n; uint64 k, dbid, dbid2; uint8 e; fpos = ftell(fh); i = ipodio_read_string(fh, 4 , 0 ) ; if (memcmp(ipodio_buf , "mhit " , 4 ) ! = 0 ) { printf ( " Nόt a valid iTunesDB fileW ) ; - exit ( EXIT_FAII>URE ) ;

}

// header length len = i = ipodio_read__uint32(fh, 0); len -= 8;

// total length i = ipodio_read__uint32(fh, 0);

// no. string mhod n_mhod = i = ipodio_read_uint32 (fh r 0);

// unique id i = ipodio_read_uint32(fh, 0); status.unigueid = i + 1;

// visible i = ipodio_read_uint32(fh, 0);

// filetype ipodio_read_string ( £h , 4 , STRINGJREVERSE ) ;

// type n = ipodio_read_uintl6(fh, 0);

// skip some fields fseek(fh, 2, SEEK-CUR);

// date added i = ipodio_read_uint32(fh, 0); len -= 28;

// size in bytes i = ipodio_read_uint32(fh, 0);

// length in ms i = iρodio_read_uint32(fh, 0);

// track number i = ipodio_read_uint32(fh, 0);

// total tracks i = ipodio_read_uint32(fh, 0);

// year i = ipodio_read_uint32(fh, 0);

// bit rate i = ipodio_read_uint32(fh, 0); fseek(fh, 2, SEEK_CUR); len -= 26; '

// sample rate

n = ipodio_read_uintl6(fh, 0);

// volume i = ipodio_read_uint32(fh, 0);

// start time i = ipodio__read_uint32(fh, 0);

// stop time i = ipodio_read_uint32(fh, 0);

// sound check i = ipodio_read_uint32(fh, 0);

// play count i = ipodio_read_uint32(fh, 0);

// play count 2 i = ipodio_read_uint32(fh, 0);

// last time played i = ipodio_read_uint32(fh, 0); fseek(fh, 20, SEEK_CUR); Ie n _= so-

// DBID dbid = k = ipodio_read_uint64(fh r 0); status.dbid = dbid + 1;

// checked e = ipodio_read_uint8(fh, 0);

// application rating e = ipodio_read_uint8 (fh, 0); fseek(fh, Z, SEEK_CUR); len -= 12;

// artwork count n = ipodio_read_uintl6(fh, 0);

// compressed n = ipodio_read_uintl6(fh, 0); len -= 4;

// artwork actual size of image added to mp3 (the jpeg) i = ipodio_read_uint32(fh, 0);

// unkll i = ipodio_read_uint32(fh, 0);

// sample rate 2 i = ipodio_read_uint32(fh, 0);

// date released

i = ipodio_read_uint32(fh, 0);

// unkl4 i = ipodio_read_uint32 (fh, 0);

// unkl5 i = ipodio_read_uint32(fh, 0);

// unklβ i = ipodio_read_uint32(fh, 0);

// unkl7 . i = ipodio_read_uint32(fh, 0);

// unkl8 i = ipodio_read_uint32(fh, 0);

// flag 1 e = iρodio_read_uint8(fh, 0); len -= 37;

// shuffle skip e = ipodio__read_uint8(fh, 0);

// remember playback position e = ipodio_read_uint8(fh, 0);

// remember podcast e = ipodio_read_uint8(fh, 0);

// DBID 2 dbid2 = k = ipodio_read_uint64(fh, 0);

// 176 unk e = ipodio_read_uint8(fh, 0); len -= 12;

// movie file e = ipodio_read_uint8(fh, 0);

// unk20 n = ipodio_read_uintl6(fh, 0);

// unk2l i = ipodio_read_uint32(fh, 0);

// unk22 i = ipodio_read_uint32(fh, 0);

// sample count i = ipodio_read_uint32 (fh, 0);

// unk24 i = ipodio_read_uint32(fh, 0);

// unk25 i = ipodio_read_uint32(fh, 0);

// unk26 i = ipodio_read_uint32(fh, 0);

// unk27 • i = iρodio_read_uint32 (fh, 0); len -= 31;

// media type i = ipodio_read_uint32 (fh, 0); len -= 4; fseek(fh, 8, SEEK_CUR) ;

// unk31 i = ipodio_read_uint32 (fh, 0);

// unk32 i = ipodio_read_uint32(fh, 0);

// unk33 i = ipodio_read_uint32 (fh, 0);

// unk34 i = ipodio_read_uint32(fh, 0);

// unk35 i = ipodio_read_uint32 (fh, 0);

// unk36 i = ipodio_read_uint32(fh, 0);

for(i = 0; i < n_mhod; i++) { itunesdb_read_mhod(fh) ; }

// mhit is not 0-padded return(O) ; }

*

* read a track list (MHLT) * uint3.2 itunesdb_read_mhlt ( FILE *fh)

{ uint32 i, len; state * st; st = &(mhyp_state[mhsd_count) ) ;

i = ipodio_read_string(fh, 4, 0); if (memcmp(ipodio_buf, "mhlt", 4) != 0) { printf("Nυt a valid iTunesDB file\n"); exit(EXIT_FAILURE ); }

// header length len = i = ipodio_read_uint32(fh, 0); st->offset = ftell(fh);

// song count i = ipodio_read_uint32 (fh, 0); st->length = i; fseek(fh, len - 12, SEEK__CUR); len = i; for(i = 0; i < len; i++) { itunesdb_read_mhit( fh) ; } st->offset_entries = ftell(fh); return ( 0 ) ;

*

* read a dataset (MHSD) * uint32 itunesdb_read_mhsd(FILE *fh)

{ uint32 i, len, tot, fpos; state * st; st = &(mhsd_state[mhsd_count] ) ; i = ipodio_read_string(fh, 4, 0); if (memcmp(ipodio_buf, "mhsd", 4) != 0) { printf("Not a valid iTunesDB file\n"); exit(EXIT_FAILURE) ; }

// header length len = i = ipodio_read_uint32(fh, 0);

// total length tot = i = ipodio_read_uint32(fh, 0);

// type st->type = i = ipodio_read_uint32 (fh, 0);

fpos = ftell(fh); st->length = tot; st->offset = fpos - 8; // byte position of total length field fseek(fh, len - 16, SEEK_CUR); if(i == 1) { itunesdb_read_mhlt(fh) ;

} else {

, itunesdb_read_mhlp(fh) ; } mhsd_count++ ; returή(O) ;

*

* read the database (MHBD)

* uint32 itunesdb_read_mhbd(FILE *fh) { uint32 i, len, k; i = ipodio_read_string(fh, 4, 0); if (memcmp(ipodio_buf, "mhbd", 4) != 0) { printf("Not a valid iTunesDB file\n"); exit (EXIT_FAILURE ) ; }

// header length len = i = ipodio_read_uint32(fh, 0); mhbd_state.offset = ftell(fh);

// total length i = ipodio_read__uint32(fh, 0); mhbd_state. length = i; f ' seek(fh, 4, SEEK_CUR);

// iTunes version i = ipodio_read_uint32(fh, 0);

// no. children i = ipodio_read_uint32(fh, 0); fseek(fh, len - 24, SEEK_CUR) ; for(k = 0; k < i; k++)> { itunesdb_read_mhsd( fh) ;

} return ( 0 ) ;

}

* create new playlist item (MHIP) * uint32 itunesdb_new_mhip(uint8** ptr) { uint8 *mhip = ' calloc(120, 1), *tag = (uintδ *)"pihm", *tag_mhod = (uint8 *)"dohm"; uint32 nbytes; uint64 164; uint32 132; uintlδ 116; uintδ iβ;

*ptr = mhip; ipodio_set__uintn(mhip, 0, tag, 4); x32 = 76; // header length ipodio_set_uintn(mhip, 4, &i32, 4); i32 = 120; // total length ipodio_set_uintn(mhip, 8, &i32, 4); i32 = 1; // mhod count iρodio_set_uintn(mhip, 12, &i32, 4); i32 = 0; // podcast group flag ipodio_set_uintn(mhip, 16, &i32 f 4); i32 = 0x0; //15515; // group id ' ipodio_set_uintn(mhip, 20, &i32, 4); i32 = status. uniqueid; // track id ipodio_set_uintn(mhip, 24, &i32, 4);

132 = 0x0; // Oxbffcflaβ; // timestamp ipodio__set_uintn(mhip, 28, Si32, 4);

1 i32 = 0; // podcast grouping reference ipodio_set_uintn(mhip, 32; &i32, 4);

// now create mhodlOO ipodio_set_uintn(mhip, 76, tag_mhod, 4);

' i32 = 24; // header length ipodio_set_uintn(mhip, 80, &i32, 4); i32 = 44; // total length ipodio_set_uintn(mhip, 84, &i32, 4); i32 = 100; // type

ipodio_set_uintn(mhip, 88, &i32, A); // skip 8 unk bytes i32 = status. uniqueid;// 15515; ipodio_set_uintn(mhip, 100, δi32, 4); return (120); }

*

* create a new MHOD entry in memory * mhod fields set by MDA:

6 types:

1 title, 2 location, 3 album, 4 artist, 5 genre, 6 filetype offset size name . value

8 4 total length

12 4 type

28 4 length in bytes If the string is UTF-16, each char takes two bytes.

40 length the string

mhod non-zero default fields: offset size name value

0 4 id mhod

4 4 header length 0x18

*/ uint32 itunesdb new mhod(uint8 ** ptr, uint32 type, uintβ *s) / I uintβ *mhod, *tag = (uintβ *) "dohiυ" ; uint32 nbyfces ; uintβ4 i64; uint32 i32; uintlδ il6; uintβ ±8; if(type < 15) { nbytes = 0x18 + 0x10 + (strlen{ (char *)s) * 2); *ptr = -mhod = calloc( nbytes, 1); ipodio_set_uintn(mhod, 0, tag, 4); i32 = 0x18? ipodio_set_uintn(mhod, 4, &ϊ32, 4);

// wait until after to set total length

// set the mhod type ipσdio_set_uintn(mhod, 12, stype, 4);

// set "position" i32 = 0x1; ipodio_set_uintn(mhod, 24, Si32, 4);

// string length i32 = strlen((char *)s) * 2; ipodio_set_uintn(mhod, 28, &i32, 4);

// set "UTFl 6" i32 = OxI; ipodio_set_uintn(mhod, 32, Si32, 4);

// set the string i32 = strlen( (char *)s); ipodio_set_utf16(mhod, 40, S / i32);

// now set the total length ipodio_set_uintn(mhod r 8, Snbytes, 4);

} else {

// unsupported MHOD . nbytes = 0;

return ( nbytes ); // return the length of the mhod

}

*

* create a new MHXT entry in memory * mhit fields set by MDS: offset size name value

8 4 total length (mcl. mhods)

16 4 unique id

24 4 filetype iTunes 4.7.1 (and greater) writes out the file's typ

28 2 type CBR MP3s are type 0x100, VBR MP3s are type 0x101, M

32 ??? 4 date added

36 4 Size of track in bytes

40 4 length of track xn ms

56 4 bit rate

€2 4 sample rate

112 8 dbid Unique 64 bit value that identifies this song across

124 2 artwork count The number of album artwork items put into the tags

128 4 artwork size The total size of artwork (in bytes) attached to thi

136 4 sample rate 2 The sample rate of the song expressed as an IEEE 32

144 4 unk unknown, but MP3 songs appear to be always OKOOOOOOO

166 1 remern playback pos on when 0x1

167 1 flag 4 When this flag is set to 0x1 then the "Now playing"

168 8 dbid2 same as dbid

177 1 movie file flag if 0x1, at is a movie file. Otherwise, it is an audi

208 4 media type 0x00 00 00 01 - Audio, 0x00 00 00 02 - Video, 0x00 0 mhit non-zero default fields:

offset size name value

0 4 id mhit

4 4 header length 0xf4

12 4 n strings 7

20 4 visible 1 '

126 2 unk9 unknown, but always seems to be Oxffff for MP3/AAC songs, 0x0 fo

164 1 flag 1 0x2

165 1 shuffle skip 0x1

178 2 unk 0x1

200 4 unk unknown (added in dbversion OxOc). Seems to have something to do

204 4 unk unknown - added in dbversion OxOc, first values observed in OxOd uint32 itunesdb new mhit(uinta **ptr, track *tr) { uint8 *mhit = calloc(BYTES_MHlT + 48, 1), *tag = (uintβ *)"tihm"; // add 48 to have lengths uint8 *mhod_title, *mhod_location, *mhod_album, *mhod_artist r *mhod_genre, *mhod_filetype; uint32 nbytes, nl, n2, n.3, n4, n5, n6; uint64 i64; uint32 i32; uintlβ ilδ; uinta i8 ;

*ptr = mhit; ipodio_set_uintn(mhit, 0, tag, 4); nbytes = i32 = 0xf4; ipodio_set_uintn(mhit, 4, si32, 4);

// set total size after creating mhod objects i32 = status.πthod_count; // n strings (mhod objs) ±podio_set_uintn(mhit, 12, Si32, 4); i32 = status.uniqueid; // unique id ipodio_set_uintn(mhit, 16, Si32, 4); i32 = 0x1; // visible ipodio_set_uintn(mhit, 20, Si32, 4);

// ' 20060127 doesn't appear necessary

X32 = 0x0; // 0x4d503320; // " 3PM" -> "MP3 " ipodio_set_uintn(mhit, 24, &i32, 4);

// 20060127 doesn't appear necessary

116 = 0x0; // 0x0101; // CBR = 0x100, VBR = 0x101 ipodio_set_uintn(mhit, 28, 5til6, 2);

/*

Doesn't appear necessary * i32 = 0xbff2bb70; // date added ipodio_set_uiπtn(mhit, 32, &i32, 4); */

// 20060127 doesn't appear necessary

i32 = OxO; // tr->bytes; // 54675; // size of track in bytes - 64675 ipodio_set_uintn(mhit, 36, Si32, 4);

// 20060127 doesn't appear necessary i32 = OxO; /I tr->milliseconds; // 10396; // length of track in ms ipodio_set_uintn(mhit, 40, Si32, 4);

// 20060127 doesn't appear necessary

132 = 0x0; // tr->bit_rate; // 47; // bit rate 47 kbps VBR ipodio_set_uintn(mhit, 56, Si32, 4);

// 20060127 doesn't appear necessary i32 = 0x0; // tr->sampls_rate; // 44100; // sample rate 44.100 khz ipodio__set_uintn(mhit, 62, &i32 r 4);

/*

Doesn't appear necessary

* i32 = 0xl7a; // sound check ipodio_set_uintn(mhit, 76, &i32, 4); */ i64 = status. dbid; // dbid ipodio_set_uintn(mhit, 112, Si64, 8); il6 = tr~>artwork_count; //OxO; // artwork count ipodio_set_uj.ntn(mhit, 124, &il6, 2); il6 = Oxffff; // unk9 ipodio_set_uintn(mhit, 126, &il6, 2);

// 20060127 doesn't appear necessary i32 = 0x0; // tr->artwork_bytes ; // 0x0; //0x0; // artwork size (the actual 3peg data size ipodio_set_uintn(mhit, 128, &i32, 4);

/* *

Doesn't appear necessary * i32 = 0x472c4400; // 0x472c4400; // sample rate 2 _.podio_set_u-.ntn(πιhit, 136 , &i32, 4); */ i32 = OXOOOOOOOC; // = "mp3 see notes above unkl4 ipodio_set_uintn(mhit, 144, Si32, 4)f i8 = 0x0; /// 0x2; // flag 1 ipodio_set_uintn(mhit, 164 , Sά8, 1); i8 = OxI; // shuffle skip ipodio_set_uα.ntn(mhit, 165 , Sα8, 1); i8 = OxO; // remember playback position ipodio_set_uintn(mhit, 166 r Si8, 1);

/*

Don't appear necessary i8 = OxO; // now playing (no artist shown if 0x1) iρodio_set_uintn(mhit, 167, Si8, 1);

*/

//. USED FOR PHOTOS? i64 = status.dbid; // dbidZ ipodio_set_uintn(mhit, 168, &i64, 8);

i8 = 0x0; // movie file flag ipodio_set_uintn(mhit, 177, &i8, 1);

/*

*

Don't appear necessary to iPod use

* il6 = 0x2; Il unk 20 1 or 2 = podcast ???? ipodio_set_uintn(rah.it, 178, &il6, 2);

// unk22 @ 184 i32 = 0x210; ipodio_set_uintn(mhit, 184, &132, 4);

// sample count ϊ32 = 0x6ed30; ipodio_set_uintn(mhit, 188, &i32, 4); i32 = 0xb40; //0κ892; //0xb56; // unk 26; something to do with iTunes MP3 encoder ipodio_set_uintn(mhit, 200, &i32, 4); i32 = OxI; // unk 27; something to do with iTunes MP3 encoder ipodio_set_uintn(mhit, 204, &i32, 4); */ i32 = tx->media_type; // media type ipodio_set__uintn(mhit, 208, &i32, 4);

// create 6 mhod entries nl = itunesdb_new_mhod(&mhod_title, 1, (uint8 *)tr->title) ; n2 = itunesdb_new_mhod(Smhod_location, 2, (uintβ *)tr->location) ; n3 = itunesdb_new_mhod(Smhod_album, 3, (uint8 *)tr->album) ; n4 = itunesdb_new_mhod(Smhod_artist> 4, (uintδ *)tr->artist) ; n5 = itunesdb_new_mhod(δmhod_genre, 5, (uintβ * )tr->genre ) ; n6 = itunesdb_new_mhod(Smhod_filetype, 6, (uint8 *)tr->filetype) ; nbytes += nl + n2 + n3 + n4 + n5 + n6;

// now set mhit total size ipodio_set__uintn(mhit p 8, Snbytes, 4);

*(uint32 *)(mhit + 0xf4) = nl;

*(uint32 *){mhit + 0xf4 + 4) = (uint32) mhod_title;

*(uint32 *)(mhit + 0xf4 + 8) = n2;

*(uint32 *)(mhit + 0xf4 + 12) = (uint32) mhod_location;

*(uint32 * ) (mhit 0xf4 + 16) = n3 ?

*(uint32 *) (mhit + 0x£4 + 20) = (uint32) mhod_album;

*(uint32 *) (mhit + 0xf4 + 24) = n4;

*(uint32 *) {mhit + 0xf4 + 28) = (uint32) mhod_artist;

*(uint32 *) (mhit + 0xf4 + 32) = n5;

*(uint32 *) (mhit + 0xf4 + 36) = (uint32) mhod_genre;

*{uint32 *) (mhit + 0xf4 + 40) = n6;

*(uint32 * ) (mhit + 0xf4 + 44) = (uint32) mhod filetype; return(nbytes ); // return the length of the mhit

*

* remove the MHIT and MHODs from memory * uint32 itunesdb_free_mhip(uint8 *mhip)

{ free(mhip); return( 0 ) ; }

*

* remove the MHIT and MHODs from memory * uint32 itunesdb_free_mhit(uint8 *mhit) { uint32 offset = 4; free((uint8 *)(*(uint32 *)(mhit + 0xf4 + offset))); offset += 8; free((uint8 *)(*(uint32 *)(mhit + 0xf4 + offset))); offset += 8; free((uint8 *) (*(uint32 *) (mhit + 0xf4 + offset))); offset += 8; free((uint8 *)(*(uint32 *)(mhit + 0xf4 + offset))); offset += 8; free((uint8 *)(*(uint32 *)(mhit + 0xf4 + offset))) ? offset -H= 8; free((uint8 *)(*(uint32 *)(mhit + 0xf4 + offset))); ' free(mhit); return( 0 ) ;

* write the header of an MHSD of type based on mshd<rahsd_index>_state->type * uint32 itunesdb_write_mhsd_header(FILE *fh_in, FILE *fh_out r uint32 mhsd_index )

uint32 i, nbytes; state *mhyp_st, *mhsd_st; uint8 buf [ 4 ] ; mhsd_st = s.<mhsd_state [mhsd_index] ) ; mhyp_st = & (mhyp_state [mhsd_index] ) ; if(mhsd_st->type == 1) { nbytes = status.mhit_bytes; } else { nbytes = status.mhip_bytes + (status.mhod52_count * 4 * status.new_entries ); // 4 bytes

>

// copy to mhsd for(i = ftell(fh_in); i < mhsd_st->offset; i++) { fputc(fgetc ( fh_in) , fh_out) ;

}

// update the mhsd byte length value i = mhsd_st->length + nbytes ; ipodio_set_umtn (buf , 0 , si, 4 ) ; fwrite(buf, 1 , 4 , fh_out) ;

// skip 4 bytes in fh_in fseek(fh_in, 4, SEEK_CUR);

// copy to mhlt/mhyp for(i = ftell(fh_in); i < mhyp_st->offset; i++) { fputc(fgetc(fh_in) , fh_out) ; } if(mhsd_st->type == 1) {

// now update mhlt song count , i = mhyp_st->length + status.new_entries; // this would be + number of new tracks ipodio_set_uintn(buf, 0, Si, 4); fwrite(buf, 1, 4, fh_out);

> else {

// update mhyp_state.length i = mhyp_st->length + nbytes; ipodio_set_uintn(buf, 0, Si, 4); fwrite(buf, 1, 4, fh_out)? fseek(fh_in, 4, SEEK_CUR); // jump over what we just updated

// copy to mhyp_state.offset_count for(i = ftell(fh_in); i < mhyp_st->offset_count ? i++) { fputc(fgetc(fh_in) , fh_out);

}

// update rahyp_state.count i = mhyp_st->count + status.new_entries; // this is + number of new tracks ipodio_set_uintn(buf, 0, si, 4); fwrite(buf, 1, 4, fh_out); }

// skip 4 bytes in fh_xn fseek(fh_in, 4 P SEEK_CUR);

return ( 0 ) ;

* write the header and body of MHSD type 2 *

** **/ uint32 a.tunesdb_write_mhsd2(FILE *fh_in, PILE *fh_out, uint32 mhsd index) { uint32 i f offset, k, j; state *mhyp_st, *mhod_st; mhi *mhip; uintδ buf[4], *mh; itunesdb_write_mhsd_header(fh_in, fh_out r mhsd_index) ; mhyp_st = &(mhyp_state[mhsd_index] ); offset = (mhsd_indθκ == 0 | | (mhsd_index -- 1 SS mhsd_state[ 0] .type == 1)) ? 0 : 5;

// update playlist mhod entries for(k = 0 »- offset; k < S + offset; k++) { inhod_st = & (mhod_state [ k] ) ;

// copy to mhodn_state. offset for(i = ftell(fh_in); i < mhod_st->offset; i++) {

£putc ( fgetc ( fh_in) , fh_out) ; >

// update mhodn_state. length

1 = mhod_st->length + ( status.new_entries * 4); // n new entries * 4 xpod_.o_set_uintn(bu£, 0, Si, 4); fwrite(buf, 1, 4, fh_out); fseek{fh_αn, 4, SEEK_CUR); // jump over what we just updated

// copy to mhodn_state.offset_count for(i = ftell(fh_xn) ; i < mhod_st->offset_σount; i++> { fputc(fgetc( £h_in) , fh_out) ,- }

// update mhodn_state.count

1 = nUiod_st->count + status ,new_entries; // n new tracks iρodao_set_uintn(buf r 0, Si, 4); fwrite(buf, 1, 4, fh_out); fseek(fh_in, 4, SEEK_CUR); // jump over what we just updated

// copy to mhodn_state.offset_entries for(i = ftell(fh_in) ; i < mhod_st->o£fset_entries; i+4-) { fputc(fgetc(fh_in), fh_out); }

// append new track ids to index list of mhod for(j = 0; j < status.new_entries; j++) { mhip = mhip_list[3]; roh = mhip->object; i = mhyp_st->count + j; // this will need to change - wxll start at mhyp<n>_state->c ipodio_set_uxntn(buf, 0, &i, 4); fwrite(buf, 1, 4, £h_out);

}

// copy to mhypn_state.offset_entries for(i = ftell(fh_in); i < mhyp_st->offset_entries ; i++) { fputc(fgetc(fh_in) , fh_out); }

// now actually write new playlist item(s) for(j = 0; j < status.new_entries; j++) { mhip = inhip_list[ j ] ; mh = mhiρ->object; fwrite(mh, 1, mhip->length, fh_out); } return(O) ; }

*

* write the header and body of MHSD type 3 * uint32 itunesdb_write_mhsd3(FILE *fh_in, FILE *fh_out, uint32 mhsd_index)

< return(itunesdb_write_mhsd2 ( fh_in, fh_out, mhsd_index) ) ; }

*

* write the header and body of MHSD type 1

•A uint32 itunesdb_write_mhsdl ( FII>E *fh_in, FILE *fh_out, uint32 mhsd_index)

{ uint32 i, len, offset, k, nbytes; state *mhyp_st; mhi *mhit; uintβ buf[4], *mh; itunesdb_write_mhsd__header(fh_in, fh_out, mhsd_index) ; mhyp_st = &(mhyp_state[mhsd_indexj);

// copy to end of mhit entries for(i = ftell(fh_in); i < mhyρ_st->offset_entries; i++) { fputc(fgetc(fh_in) , fh_out) ; }

// now add new mhit(s) for(i = 0; i < status.new_entries; i++) { mhit = mhit_list[i] ; mh = mhit->object; k. = status.mhod_count * 8; fwrite(mh, 1, 0xf4, fh_out); // MHIT is always size 0xF4, pull this value out. for(offset = 0; offset < k; offset += 8) {

len = *<uint32 *)(mh + 0xf4 + offset); fwrite((uint8 *)(*(uint32 *)(mh + 0xf4 + offset + 4)), 1, len, fh_out);

} } return(O) ;

}

/***+

*

* initialize some properties

*

+***/ uint32 itunesdb_init( ) { uintlδ endian = 0x0001; defaults . sample_rate = 44100; status.dbid = OxILL;

Status.uniqueid = 1; status.new_entries = 0; status.mhod_count = 6; status.mhod52_count = 5; status.mhit_bytes = 0; status.mhip_bytes = 0;

// determine the endian-ness of the system big_endian = (*(uintβ *)&endian == 0x01) ? 0 : 1; return{ 0 ) ;

*

. * enter here * int main(int argσ, char** argv)

{ uint8 *mhit, *mhip, buf[4], ch; uint32 i, nbytes_mhit, nbytes_mhip, fpos;

FILE *fh, *fh_out; mhi *mh; track tl r t2 , *t; uint32 n_tracks = 1; // 2; itunesdb_init( ) ; . tl.bytes = 64675; tl.milliseconds = 10396; • tl.bit_rate = 47; tl.samρle_rate = 44100; tl.artwork_count = 1;

tl.artwork_bytes = 26364; tl .media_type = 1; tl.title = "Title #1"; tl. location = " : xPod_Control:Music:Modality:TEST.mp3" ; tl.album = "Album #1"; tl.artist = "Modality Learning"; tl.genre = "Books S Spoken"; tl.filetype = "MJPEG audio file"; tl.next = &t2;

/* t2.bytes = 64675; t2.milliseconds = 10396; t2.bit_rate = 47; t2.sample_rate = 44100; t2.artwork_count = 0; t2. artwork_bytes = 0 ; t2.media_type = 1; t2 -title = "Title #2"; t2. location = " :iPod_Control:Music:Modality:TEST2.mp3"; t2.album = "Album #2"; t2. artist = "Modality Learning"; t2. genre = "Books & Spoken"; t2.filetype = "MPEG audio file"; */

// fh = fopen( " iTunesDB_art" , "rb" ) ; // fh = fopen("'iTunesDB_l 11 , "rb"); // fh = fopen("iTunesDB_out","rb"); fh = fopen( " iTunesDB_blank" , "rb" ) ; itunesdb_read_mhbd( fh) ; return(O) ;

// rewind and update rewind( fh) ; t = StI; for(i = 0; i < n_tracks; i++) { nbytesjonhit = itunesdb_new_mhit(Smhit, t); nbytes_mhip = itunesdb_new_mhip(&mhip) ; mh = mhit_list[i] = calloc(l, sizeof (mhi) ) ; mh->object = mhit; mh->length = nbytes_mhit; mh = mhip_list[i] = calloc(l, sizeof (mhi) ); mh->object = mhip; mh->length = nbytes_mhip; status.mhit_bytes += nbytes_mhit; status.mhip_bytes += nbytes_mhip; status .new_entries++;

statU3.dbid++; status. uniqueid++; t = t->next; }

// ' the new size of mhbd is nbytes + nbytes_mhip * 2 + n * 4.* 5 * 2, where n is no. new trac fh_out = fopen( ! 'iTunesDB_out", "wb" ) ; for(i = 0; i < 3; i++) .{ switch(mhsd_state[i] .type) { case 1: itunesdb_write_mhsdl(fh, fh_out, i); break; case 2: itunesdb_jwrite_mhsd2(£h, £h_put p i); break; case 3: itunesdb_write_πthsd3(£h, fh_out, i); break; } >

// set new mhbd value fpos = ftell ( fh_out) ; // remember where we are before we jump back to the beginning fseek(fh_out, mhbd_state.offset, SEEK-SET); i = mhbd_state. length + status.mhit_bytes + ( (status .mhip_bytes + status.itihod52_count * 4 * ipodio_set_uintn(buf, 0, &i r 4); fwrite(buf, 1, 4, fh_out); fseek(fh_out, fpos, SEEK-SET); // now finish copying... while(l) { ch = fgetc(fh); if(feof(fh) ) { break; } else { fputc(ch, fh_out); } } • •

// done fclose ( fh_out ) ; fclose(fh);

// free mhifc and mhodε for(i = 0,- i < status .new_entries ; i++) { mh = (mhi *)tnhit_list[i] ; itunesdb_£ree_mhit(mh->object) ; mh = (mhi * )mhip_list[i) ; . itunesdb_free_mhip(mh->object) ;

free(mhit_list[i] ) ; free(mhip_list[i] ); } return ( 0 ) ;

#ifdef cplusplus extern "C" } #endif

VIDEO model:

Pyramis

424 songs

2 videos

46 photos

27.8 GB capacity

26.8 available version 1.1

S/N JQ5439FVSZ9

Model MAO02LL

Sysinfo file: BoardHwName: iPod M25 pszSerialNumber: JQ5439FVSZ9 ModelNumStr: MAO02 FirewireGuid: 0x000A270014806815 HddFirmwareRev: BUlIlA RegionCode: LL(OxOOOl) PolicyFlags: 0x00000002 buildID: 0x06108000 (6.1) visibleBuildlD: 0x01108000 (1.1) boardHwRev: 0x00000000 (0.0 0) boardHwSwInterfaceRev: OxOOOBOOOS (0.0.11 5] bootLoaderlmageRev: 0x00000000 (0.0 0) diskModelmageRev: 0x00000000 (0.0 0) diaglmageRev: 0x00000000 (0.0 Q) osImageRev: 0x00000000 (0.0 0) iPodFamily: 0x00000000 updaterFamily ' : 0x00000000

GEN4 model: Duke

1 songs

2 photos

18.5 capacity 18.5 available version 1.2 S/N JQ53449YTDU Model PAO8ILL

Sysinfo file: BoardHwName: iPod P98 pszSerialNumber: JQ53449YTDU ModelNumStr: PA081 FirewireGuid: 0x000A2700146E2238 HddFirmwareRev: BY301A RegionCode: LL(OxOOOl) PolicyFlags: 0x00000000 buildID: 0x04218000 (4.2.1) visibleBuildID: 0x01218000 , (1.2.1) boardHwRev: 0x00000000 (0.0 0) boardHwSwInterfaceRev: 0x00060004 (0.0.5 4) bootLoaderlmageRev: 0x00000000 (0.0 0)

diskModelmageRev: 0x00000000 (0.0 0) diaglmageRev: 0x00000000 (0.0 0) osImageRev: 0x00000000 (0.0 0) iPodFamily: 0x00000000 updaterFamily: 0x00000000

GEN4 model: macito 478 songs 6 photos

55.8 GB capacity

52.9 GB available Version 1.2

S/N JQ5180RRSAZ Model M9830LL

Sysinfo file: BoardHwName: iPod P98 pszSerialNumber: JQ5180RRSAZ ModelNumStr: M9830 FirewireGuid: 0x000A270014320Dl7 HddFirmwareRev: BYOO2A RegionCode: LL(OxOOOl) PolicyFlags: 0x00000000 buildID: 0x04208000 (4.2) visibleBuildID: 0x01208000 (1.2) boardHwRev: 0x00000000 (0.0 0) boardHwSwInterfaceRev: 0x00060000 (0.0.6 0) bootLoaderlmageRev: 0x00000000 (0.0 0) diskModelmageRev: 0x00000000 (0.0 0) diaglmageRey: 0x00000000 (0.0 0) osImageRev: 0x00000000 (0.0 0) iPodFamily: 0x00000000 updaterFamily: 0x00000000 ibleBuildID: ' 0x01108000 (1.1) whoWasHere: Updater

NANO model: buildID: 0x05008000 (5.0)

GEN2 model: macito

Capacity 9.2 GB Available 275 MB Version 1.5 S/N U22333FHMMB

Sysinfo file: pszBoardHwName: iPod P97 pszSerialNumber: U22333FHMMB puδFirewireGuid: 0x0004FlF0 buildID: 0x01508000 (1.5) boardHwRev: 0x00000000 (0.0 0) boardHwSwInterfaceRev: 0x00020000 (0.0.2 0)

bootLoaderlmageRev: 0x00010000 (0.0.1 0) diskModelmageRev: 0x00000000 (0.0 0) diaglmageRev: 0x00000000 (0.0 0) osImageRev: 0x00000000 (0.0 0) oemv: 0x00000001

gcc artworkdb.c ipodio.c -o artworkdb_reader check if we can reference our own M1017_l..ithmb etc. to do: finish up new mhba and new mhif add code for new mhia check mhlf in photo database check if can reference M101x_l. ithmb etc. track ithmb byte offset

- photo database mhlf

Header length = 92

No. files = 4 mhif

Header length = 124

Total length = 124

Correlation ID = 1019

Image size in bytes = 691200 mhif

Header length = 124

Total length = 124

Correlation ID = 1020

Image size in bytes = 77440 mhif.

Header length = 124

Total length = 124

Correlation ID = 1009

Image size in bytes = 2520 mhif

Header length = 124

Total length = 124

Correlation ID = 1015

Image size in bytes = 22880

ArtworkDB ithmb:

Photo iPod

F1017_l.ithmb = 6272 - 56x56

P1016_l. ithmb = 39200 - 140x140

Video iPod:

F1028_l.ithmb = 20000 - now playing thumbnail - 100x100 F1029_l.ithmb = 80000 - larger thumbnail - 200x200

Nano:

F1031_l.ithmb = 3528 - 42x42

F1027 l.ithmb = 20000 - 100x100

formats : video:

1019 = 720x480 1015 = 130x88 1024 = 320x240 1036 = 50x41 Correlation ID 1019 Image size in bytes 691200 Correlation ID 1015 Image size in bytes 22880 Correlation ID 1024 Image size in bytes 153600 Correlation ID 1036 Image size in bytes 4100 nano:

1023 = 176x132 1032 = 42x37 Correlation ID 1023 Image size in bytes 46464 Correlation ID 1032 Image size in bytes 3108 gen4:

1019 = 720x480

1020 = 220x176 1009 = 42x30 1015 = 130x88 Correlation ID 1019 Image size in bytes 691200 Correlation ID 1020 Image size in bytes 77440 Correlation ID 1009 Image size in bytes 2520 Correlation ID 1015 Image size in bytes 22880

691200 + 153600 + 22880 + 4100

46464 + " 3108

77440 + 2520 + 22880

= -1MB

Photo = 1MB Artwork = .15MB

Example :

30 MB for 100 images

165 MB for 500 images

Things to check-

- correlation id - can we use Modality-specific?

- check on photo dimensions for nano, video, gen4

- need to use correlation id's but can point to a Modality file

*/

#include <stdlib.h> #include <stdio.h> #include <string.h> #include "ipodio.h"

#ifdef cplusplus extern "C" { #endif

// needs vars for struct

{ uint32 uniqueid; uint32 new_entries; uint32 new_albums; uint32 ipod_type; uint32 db_mode; uint32 playlist_id; // track playlist ids uint32 fl017_ithmb; // byte offset in ithmb uint32 flO16_ithmb; // byte offset in ithmb uint32 £1015__ithmb; // byte offset in ithmb uint32 flOO9_ithmb; // byte offset in ithmb uint32 fl019_ithmb; // byte offset in ithmb uint32 fl020_ithmb; // byte offset in ithmb } status; typedef struct { uintβ -*string; // could be file name (location) uintlβ padding_top; uintlδ padding_left; uintlβ height; uintlβ width; } image_format; typedef struct

{ uint32 nbytes_original; // original size in bytes uint32 uniqueid; // based on status.uniqueid uintβ4 dbid; // links to iTunesDB entry } image_descriptor; typedef struct { image_descriptor attributes; image_format flOlβ; image_format flO17; image_format flO19; image_format flO2O; image_format fl009; image_format flO15; uint8* mhii; uint32 mhii_length; uint8* mhod[ 4 ] ;

uint32 mhod_lengths[4 J ; u±nt8* mhni[4]; uint32 mhni_lengths[4 J ; artworkdb_image;

typedef struct t uintδ *mhba; uint8 *string; // album name uint32 items [512]; // list of mhia ids to include in list uint32 nitems ;

} photodb_album;

artworkdb_image *image_list[1024] ; photodb_album *album_list[64];

uint32 mhsd_count = 0; state mhfd_state; state mhsd_state { 3 ] ; state mhli_state[ 3 ] ;

// const vars const artworkdb_nmhfi = 2; // number of mhif entries per new mhlf const artworkdb_nmhni = 2; // number of mhni entries per new mhii const photodb_nmhfi = 4; const photodb_nmhni = 4 ; const db__photo = 1; const db_artwork = 0; const mhsd^jtype^mages = 1; const mhsd_type_albums = 2; const mhsd_type_files = 3;

// prototype this one... uint32 artworkdb_read_mhod(FILE *fh);

inline uint32 artworkdb_get_ithmb__offset(uint32 th_id)

{ uint32 i; switch (th_id) { case 9017: case 1017: i = status.flO17_ithmb; ' break; case 9016: case 1016: i = status. flO16_ithmb; break;

case 1009 : i = status. fl019_ithmb; break; case 1020: i = status. f1020_ithmb; break; case 1019: i = status. fl019_ithmb; break; case 1015: i = status. flO15_ithmb; break; } return ( i ) ;

inline u " int32 artworkdb_set_ithmb_offset(uint32 th_id, uint32 len)

{ switch(th_id) { case 1017: status.flO17_ithmb = len; break; case 1016: status.flO16_ithmb = len; break; case 1009: status.f1019_ithmb = len; break; case 1020: status.flO2O_ithmb = len; break; case 1019: status.f1019_ithmb = len; break; case 1015: status.flO15_ithmb = len; break; > return ( 0 ) ;

*

* determine byte length of image

inline uint32 artworkdb_get_image_type(uint32 n) { // n is kind of arbitrary at the moment uint32 type = 0, k = status.dbjmode, i = status. ipod_type; if (k == db_photo) { // photo database switch(n) { •case 0:

type = 1009; break; case 1: type = 1015; break; case 2: type = 1019; break; case 3: type = 1020; break;

>

} else { // artworkdb switch(n) { case 0: type = 1016; //9016; break; case 1: type = 1017; //9017; break;

}

} return(type) ;

}

*

* determine byte length of image *

****( inline uint32 artworkdb_get_image_bytes(uint32 th_id)

{ uint32 nbytβs_img — 0, i = status . ipod_type; switch(th_id) { case 9016: case 1016: // full-size thumb nbytes_img = (i S IPOD_GEN4) ? 39200 : (i & IPOD_NANO) ? 20000 : 39200; break; case 9017: case 1017: // now playing thumb nbytes_img = (i & IPOD_GEN4) ? 6272 : (i & IPOD_NANO) ? 3528 : 6272; break; case 1019: // tv out nbytes_img = 691200; break; case 1020: // actual photo displayed nbytes_img = 77440; break; case 1009: // photo thumbnail nbytes_img = 2520; break; case 1015: // ???? nbytes_img = 22880; break;

} return {nbytes_img) ;

}

*

* determine which image_format structure to use * inline image_format *artworkdb_get_image_format(artworkdb_image *image, uint32 th_id)

{ image_format *£; switch (th_id) { case 9017: case 1017: f = &(image->flO17); break; case 9016: case 1016: f = &(image->f1016); break; case 1009: f = S(image->£1009); break; case 1020: f = K(image->fl020); break; case 1019: f = &(image->f1019); break; case 1015: f = Sc(image->flO15); break; } return( f) ; }

* read image name (MHNI) * uint32 artworkdb_read_π»hni(FILE *fh)

{ uin.t32 i, len, k; uintlβ il6; i = iρodio_read_string(fh, 4, 0); if(memcmp(ipodio_buf , "mhni", 4) != 0) { printf("Not a valid ArtworkDB file"); exit(EXIT_FAILURE) ; }

// header lenghh len = i = ipodio_read_uint32(fh, 0);

// total length i = ipodio_read_uint32(fh, 0);

// no. children i = ipodio__read_uint32(fh, 0);

// correlation id i = ipodiσ__read_uint32 (fh, 0);

// ithmb offset i = ipodiσ_read_uint32 (fh, 0);

// image size in bytes i = ipodiσ__read_uint32(fh, 0);

// top padding il6 = ipodio_read_uintl6(fh, 0);

// left padding il6 = ipod±o_read_uintl6(fh, 0);

// height il6 = iρodio_read_uintl6(fh, 0);

// width il6 = ipodio_read_uintl6(fh, 0); fseek(fh, len - 36, SEEK_CUR); artworkdb_read_mhod(fh) ; return( 0 ) ;

*

* read image item (MHII) * uint32 artworkdb_read_mhii(FILE *fh) { uint32 i, len, k; uint64 i64; i ~ ipodio_read_string(fh, 4, 0); if(memcmp(ipodio_buf, "mhii", 4) I= 0) { printfC'Not a valid ArtworkDB fileW); exit(EXIT_FAILURE) ; }

// header length len = i = ipodio_read_uint32 (fh, 0);

// total length i = ipodio__read_uint32 (fh, 0);

// no. images k = i = ipodio_read_uint32(fh, 0);

// ID i = ipodio_read_umt32 (fh, 0);

// DBID i64 = ipodio_read_uint64(fh, 0); fseek(fh, 20, SEEK_CUR) ;

// source image size i = ipodio_read_uint32(fh, 0); fseek(fh, len - 52, SEEK_CUR) ; for(i = 0; i < k; i++) { artworkdb_read_mhod( fh) ; } return{0 ) ; }

*

* read album item (MHIA) * uint32 artworkdb_read_mhia(FILE *fh)

{ uint32 i, len; uint64 i64; i = ipodio_read_string(fh, 4, 0); if (memcmp(ipodio_buf , "mhia", 4) != 0) { printf("Not a valid ArtworkDB file\n"); exrt(EXIT_FAILURE) ? }

// header length len = i = ipodio_read_uint32(fh, 0);

// total length i = ipodio_read_uint32 (fh, 0);

// unk i = ipodio_read_umt32(fh, 0);

// ID i = ipodio_read_uint32(fh, 0); fseek(fh, len - 20, SEEK_CUR);

return{0 ) ;

*

* read MHOD

•k **** / uint32 artworkdb_read_mhod(FILE *fh ) £ uint32 i, len, flag = O; uintl6 il6 , type ; uintβ i8 , n_padding; state *st ; i = ipodio_read_string(fh, 4, O); if(memcmρ(ipodio_buf , "mhod", 4) 1= 0) { print£("Not a valid ArtworkDB file\n"); exit(EXIT_FAII,URE) ; >

// header length lea = i = ipodio_read_uint32(fh, 0);

// total length i = ipodio__read_uint32(fh, 0);

// type 1 = name, 2 = thumbnail image, 3 = file name, 5 = full res image type = il6 = ipodio_read_uintl6(£h, 0); fseek(fh, 1, SEEK_CUR); // skip 1 byte since padding field is not byte-reversed n_padding = i8 = ipodio_read_uint8(fh, 0);

// we read 16 bytes of the header fseek(fh, len - 16, SEEK_CUR); if (type ===== i J J type == 3 ) | (type == 2 SS mhsd_state[mhsd_count] .type == 2)) { // file name

// string length len = i = ipodio_read_uint32(fh, 0);

// encoding i = ipodio_read_uint32(fh, 0); fseek{fh, 4, SEEK_CUR); if(i == 2) flag |= STRING_UTF16; flag |= STRING_TOUTF8 ;

// the string ipodio_read_string(fh, len, flag);

} else if (type == 2 | | type == 5) { artworkdb_read_mhni(fh ) ; }

if ( n_padding > 0 ) {

// slurp the padding spaces fseek( fh, n_padding, SEEK-CUR) ;

} return ( O ) ;

*

* read album list (MHBA)

* uint32 artworkdb_read_mhba(FILE *fh) { uint32 i, len, k, n_mhod, n_mhia; uint.16 il6; uint8 i8; state *st; i = ipodio_read_string( fh, 4 , O); if (memcmp(ipodio_buf, "mhba", 4) != O) { printf("Not a valid ArtworkDB file\n"); exit(EXIT_FAILURE) ; }

// header length len = i = ipodio_read_uint32(fh, 0);

// total length i = ipodio_read_uint32(fh, 0);

// MHOD child count n_mhod = i = ipodio_read_uint32(fh, 0);

// album- item count n_mhia = i = ipodio_read_uint32(fh, 0);

// playlist/album ID i = ipodio_read_uint32 (fh, 0);

// unk2 i = ipodio_read_uint32(fh, 0);

// unk3 il6 = ipodio_read_uintl6(fh, 0);

// is master library? i8 = ipodio_read_uint8(fh, 0); fseek(fh, 29, SEEK-CUR);

// previous playlist id i = ipodio_read_uint32 ( fh, 0 ) ; . fseek( fh , len - 64 , SEEK_CUR) ;

for(i = 0; i < n_mhod; i++) { artworkdb_read_mhod ( fh) ;

} for(i = 0; i < n_mhia; i++) { artworkdb_read_mhia ( fh) ; } if(i8 == 1) { // is master library playlist st = &(mhli_state[mhsd_count] ) ; st->offset_count = ftell(fh);

} return(O) ;

*

* read album list (MHLA) * uint32 artworkdb_read_mhla(FILE *fh)

{ uint32 i, len, k; state *st; st = &(mhli_state[mhsd_count] ) ; i = ipodio_read_string(fh, 4, O); if (memcmp(ipodio_buf , "rnhla", 4) != O) { printf("Not a valid ArtworkDB file\n" ) ; exit(EXIT_FAILURE) ; }

// header length len = i = ipodio_read_uint32(fh, 0); st->offset = ftell(fh);

// no. children i = ipodio_read_uint32(fh, 0); st->length = i; fseek(fh, len - 12, SEEK_CUR); for(k = 0; k < i; k++) { artworkdb_read_mhba ( fh) ; } . st->offset_entries = ftell(fh); return(O) ;

*

* ' read file item (MHIF) * uint32 artworkdb_read_mhif(FILE *fh)

{ uint32 i, len, k, tot; i = ipodio_read_string(fh, 4, 0); if(memcmp(ipodio_buf, "mhif", 4) != 0) { printf("Not a valid ArtworkDB £ile\n"); exit(EXIT_FAILURE) ' ; }

// header length len = i = ipodio_read_uint32(fh, 0);

// total length tot = i = ipodio_read_uint32(fh, 0); fseek(fh, 4, SEEK_CUR);

// correlation ID i = ipodio_read__uint32(fh, 0);

// image size in bytes i = ipodio_read_uint32(fh, 0); if(tot - 24) { fseek(fh, tot - 24, SEEK_CUR); } return(O) ;

*

* read file list (MHLF) * uint32 artworkdb_read_mhlf(FILE *fh)

{ uint32 i, len, k; state *st;

St = S(mhli_state[mhsd_count] ) ; i = ipodio_read_string(fh, 4, 0); if(memcmρ(ipodio_buf, "mhlf", 4} != 0) { printff'Not a valid ArtworkDB fileW); exit(EXIT_FAILURE) ; }

// header length len = i = ipodio_read_uint32(fh, 0);

st->o£fset = ftell(fh);

// no. files i = ipodio_read_uint32(fh, 0); st->length = i? fseek(fh, len - 12, SEEK_CUR) ;

// read mhifs fαr(k = 0; k < i; k++) { airtworkdb_read_mhi£ (fh) ; } st->of£set_entries = ftell(fh); return ( 0 ) ;

*

* read image list (MHLI) * uint32 artworkdb_read_mhli(FILE *fh) { uint32 i, len, k; state *st; st = &(mhli_state[πihsd_count J ); i = ipodio_read_string(fh, 4, 0); if(memcmp(ipodio_buf , "mhli", 4) 1= 0).{ printf("Wot a valid ArtworkDB file\n")f exit (EXIT-FAILURE ) ; } '

// header length len = i = ipodio_read_uint32 (fh, 0); st->offsβt = ftβll(fh);

// no. images i = iρodio_read_uint32(fh, 0); st->length = i; fseek(fh, lsn - 12, SEEK-CUR); for(k = 0; Ic < i; k++) { artworkdb_read_mhii ( fh) ; } st->offset_entries = ftell(fh);

return (0 ) ;

*

* read a data set (MHSD) *

** * * i uint32 artworkdb_read_mhsd(FILE *fh) { uint32 i, len; state *st;

St = &(mhsd_state[mhsd ^ _count] ) ; i = ipodio_read_string(fh, 4, 0); if (memcmp(iρodio_buf , "rohsd", 4) != 0) { printf<"Not a valid ArtworkDB fileNn"); exit ( EXIT-FAII-URK ) ; >

// header length len = i = ipodio_read_uint32(£h, 0); st->offset = ftell(fh);

// total length i = ipodio_read_uint32(fh, 0); st->length = i;

// type i = ipodio_read_uint32 (fh, 0); st->type = i; fseek(fh, len - 16, SEEK_CUR); if(i == 1) { artworkdb_read_mhli( fh) ;

} else if(i == 2 ) { artworkdb_read_mhla( fh) ;

} else { // i == 3, file list artworkdb_read_mhlf( fh) ;

} mhsd_count++; return(O) ;

*

* read artwork datafile object (MHFD) * uint32 artworkdb_read_mhfd(FILE *fh)

{ u±nt32 i, len, k, n_mhsd; i = ipodio_read_string(fh, 4, 0); if (memomp(ipodio_buf , "mhfd", 4) != 0) { printf("Wot a valid ArtworkDB file\n"); exit (EXITJFAILURE) ; }

// header length len = i = ipodio_read_uint32(fh, 0); mhfd_state.offset = ftell(fh);

// total length i = ipodio_read_uint32(fh, 0); mhfd_state.length = i;

// unk.1 i = ipodio_read_uint32(fh, 0);

// unk2 i = ipodio_read_uint32(fh, 0);

// no. children n_mhsd = i = ipodio_read_uint32 (fh, 0);

// unk3 i = ipodio__read__uint32(fh, 0); mhfd_state.offset_count = ftell(fh);

// next id for mhii i = ipodio_read_uint32(fh, 0); status.uniqueid = i; mhfd_state. count = i; fseek(fh, 16, SEEK_CUR);

/7 unk7 i = ipodio_read_uint32(fh, 0);

// unkδ i = ipodio_read_uint32(fh, 0);

// unk9 i = ipodio_read_uint32(fh r 0);

// unklO

i = ipodio_read_uint32(fh, 0);

// unkll i = ipodio_read_uint32(fh, 0); fseek(fh, len - 68, SEEK_CUR) ; for(k = 0; k < njmhsd; k++) { artworkdb_read_mhsd(fh) ; } return(O); ■ } uint32 artworkdb_new_mhod_σσntainer(uint8 **ptr, uint32 type, uint32 n_bytes_body)

{

// size ot mhod header is 0x18 uint32 mhod__header_bytes = 0x18; uint8 *tag = (uint8 *)"dohm", *mhod; uintlβ il6; uint32 i32;

*ptr = mhod = calloc(mhod_header_bytes, 1);

// set "mhod" ipodio_set_uintn(rahod, 0, tag, 4)? i

// set header size

132 = mhod_header_bytes; ipodio_set_uintn(mhod, 4, &i32, 4);

// set total size 132 += n_bytes_body; ipodio_set_uintn(κihod, 8, &i32, 4);

// set mhod type il6 = type; ipodio_set_uintn(mhod, 12, &116, 2); return(mhod_header_bytes ) ; }

*

* allocate new image item (MHNI) *

* MHNI contains MHOD type 3

A uint32 artworkdb_newjmhni<uint8 **p.tr, uint32 th_id) {

// size of itihni header is 0x4c uint32 mhni_header_bytes = 0x4c, mhod_header_bytes = 0x18; uint32 nbytes, nbytes_mhod, nbytes_img, len, n_padding, offset; uint8 ♦inhni;

uintθ *tag = (uint8 *)"mhm", *mhod_tag = (uintδ *)"dohm"; uintβ i8; uintlδ ilβ; uint32 x32, ithmb_offset; artworkdb_image *image; image_£ormat *f; image = image_list[O] ;

£ = artworkdb_get_image_format( image, th_id) ; len = strlenf (char*) (£->string)) * 2; n_padding = len % 4; nbytes = mhni_header_bytes + mhod__header_bytes + len + n_padding + 12; *ptr = mhni = (uint8 *)calloc(nbytes, 1);

// set "mhni" ipodio_set_uintn(mhni, 0, tag, 4);

// set header size i32 = mhn.i_header_bytes; ipodio_set_uj.ntn(mhni, 4, &i32, 4);

// set total size i32 = nbytes; ipodio_set_uintn(mhni, 8, &i32, 4);

// set n children i32 = 1; ipodio_set_uintn(mhni, 12, &i32, 4);

// set correlation id

132 = th_id; ipodio_set_uintn(mhni, 16, &i32, 4);

// set .ithmb offset ithmb_offset = i32 = artworkdb_get_ithmb_offset(th_id); ipodio_set_uintn(mhni, 20, &i32, 4);

// set image size in bytes i32 = artworkdb_get_image_bytes(th_id) ; ipodio_set_uitιtn(mhni, 24, &i32, 4); artworkdb_set_ithmb_offset(th_id, i32 + ithmb_offset) ;

// set top padding ilβ = f->padding_top; iρodio_set_uintn(mhni, 28, sil6, 2);

// set left padding ilβ = f->padding_left; ipodio_set__uintn(mhni, 30, Silδ, 2);

// set height ilβ = f->padding_top + f->height; ipodio_set_uintn(mhni, 32, &ilβ, 2);

// set width il6 = f->padding_left + f->width; ipodio_set_uintn(mhni, 34, &il6, 2);

// rest of header is 0-padded. // the body... offset = mhni_header_bytes;

// append type 3 mhod ipodio_get_uintn(mhni, offset, mhod_tag, 4)? offset += 4r i32 = mhod_header_bytes ; ipodio_set_uintn(mhni, offset, Sϊ32, 4); offset += 4? i32 = mhod_header_bytes + len +• n_padding + 12; // total length ipodio_sβt_uintn(mhni, offset, si32, 4); offset += 4;

116 = 0x3; // mhod type ipodio_set_uintπ(mhni, offset, Sil6, 2); offset += 2; i8 = 0; ipodio_set_uintn(mhni, offset, Si8, 1); i8 = n_padding; // padding - 1,2,3 ipodio_set_uintn(mhni, offset, 5x8, 1);

// mhod body: offset = mhni_header_bytes + mhod_header_bytes;

132 = len; // the string length ipodio_set_uintn(mhni, offset, &i32, 4); offset += 4; i32 = 2; // 2 = UTF-16? ipodio_set_uintn(mhni, offset, &i32, 4); offset += 8; // skip 4 ipodio_set_utfl6(mhni, offset, f->string f len); return (nbytes);

}

*

* allocate new image item (MHII) *

* 2 children: MHOD type 2 for full-sized thumbnail and MHOD type 2 for

* now-playing-sised thumbnail.

* Type 2 MHOD entries contain MHWI which in turn contains MHOD type 3

uint32 artworkdb_new_mhii(uint8 **ptr)

{

// size of mhii header is 0x98 = 152 uint32 mhii_header_bytes = 0x98; uint32 nbytes, nbytes_mhod, n_mhod = 0, bytes_total = 0, i, Ic; uintβ *mhii, **offset? uint8 *tag = (uintS *)"iihm"; uintl6 il6; uint32 i32, *addr; uint64 i64; artworkdb_image *image; image = image_list[0] ; // change this eventually *ptr = mhii = calloc(mhii_header_bytes, 1);

// set "mhii" ipodio_set_uintn(mhii, 0, tag, 4);

// set header size i32 = mhii_header_bytes; ipodio_set_uintn(mhii, 4, &i32, 4);

// set n children • i32 = 2? ipodio_set_uintn(mhii, 12, Si32, 4);

// set id

132 = status .uniqueid; ipodio_sefc_uintn(mhii, 16 f &i32, 4);

// set dbid - see iTunesDB entries i64 = image->attributes .dbid; ipodio_set_uintn(mhii, 20, &i64, 8);

// necessary? size in bytes of orig source image { iTunesDB entry?) i32 = image->attributes.nbytes_original; ipodio_set_uintn(mhii, 48, &i32, 4); k = (status . dbjnode == db_photo) ? photodb_nmhni : artworkdb_nmhni; for(i = 0; i < k; i++) {

// allocate a new MHOD type 2 with MHNI and MHOD type 3 bytes_total +■ » image->mhni_lengths[i] = artworkdb_new_mhni ( & ( image->mhni[i] ) , artworkdb // inhod type 2 (below) contains mnhi (above) - pass the nbytes of the new mhni to mhod t bytes_total += image->mhod_lengths[i] = artworkdb_new_mhod_container ( & ( image->mhod[ i] ) ,

}

// now set total size i32 = mhii_header_bytes + bytes_total; ipodio_set_uintn(mhii, 8, Si32, 4); status ,uniqueid++; return(mhii_header_bytes ) ;

* allocate new album (MHBA) *

* MHBA has several children. First is MHOD containing album name

* Then several MHIAs that define which images to show in that album

* Create MHIA entries at write time.

* uint32 artworJcdb_new_mhba ( uint8 **ptr) { uint32 mhba_header_bytes = 0x94; uint32 i32, nbytes = 0; uint8 buf[4], *mhba, *tag = (uintβ *)"abhm", i8; uintlβ il6; uint64 i64;

*ptr = rπhba = calloc(mhba_h.eader__bytes, 1 ) ;

// mhba ipodio_set_uintn(mhba, 0, tag, 4);

// mhba header size i32 = mhba_header_bytes ; ipodio_set_uintn(mhba, 4, £i32, 4);

// set total size later

// mhod count i32 = 1; ipodio_set_uintn(mhba, 12, &i32, 4);

// album item count i32 = 1; ipodio_set_uintn(mhba, 16, &i32,-4);

// playlist id - starts at 64? need to track as we read i32 = 1; ipodio_set_uintn(mhba, 20, 6i32, 4);

// interesting - offset 34 - show titles/captions?

// showTitles 1 show slide captions (from iPhoto setting)

// dbid2 = offset 52 - dbid2 of track to play from iTunesDB

// previous playlist id - starts at 64? need to track as we read?

132 = 1; ipodio_set_umtn(mhba, 60, &i32, 4 ) ; return (mhba_header_bytes) ; }

* write mhia entry to fh_out

* uint32 artworkdb_writa_mhia(FrLE *fh_in, PILE* fh_out, uint32 id)

{ uint32 mhia_header_bytes = 40; uint32 i32, i; uintδ bur [4 J; uint8 *tag = (uintβ *)"aihm";

// write rnhia ipodio_set_uintn(buf, 0, tag, 4); fwrite(buf, 1, 4 r fh_out);

// write the header size i32 = mhia_header_bytes; ipodio_set_uintn(buf, 0, fii32, 4); fwrite(bux, 1, 4, £h_out);

- // write the total size i32 = mhia_header_bytes; ipodio_set_ui,ntn(buf, 0, &i32, 4); fwrite(buf, 1, 4, fh_out);

// 4 0 bytes i32 = 0;

£write(&i32, 4, 1, fh_out);

// the id of the icihii record this mhia refers to i32 = id; ipodio_set_uintn.(buf, 0, &i32, 4); fwrite(buf, 1, 4, fh_out);

// rest is 0-padded i32 - 0; for(i = 16; i < mhia_header_bytes; i += 4) { fwrite(&i32 r i, 1, fh_out);

} return (0); >

*

* write mhla and children to fh_out; return number of bytes added to mhla length

A

* need to update master library list with new MHIA entries

* and add new albums * uint32 artworkdb_write_mhla ( PILE *fh_in, FILE *fh_out, uint32 index) { // mhlf or mhli uint32 i, k r j; state *st;

photodb_album *album; uinta buf[4] ; at = & (mhli_state[ index] );

// copy to mhli_state[O] .offset for(i = ftell(fh_in); i < st->offaβt; i++) { fputc(fgetc(fh_in) , fh_put);

}

// update mhia size = number of mhba entries, not byte length i - str->length + 3tatus ,new_albums; ipodio_set_uintn(buf, 0, Si, 4 ) ; fwrite(buf, 1, 4, fh_out); fseek(fh_in, 4, SEEK-CUR); // skip what we just updated

// copy to mhli_state[O] . offset_count to update master mhia list for(i = ftell(fh_in); i < st->offset_count; i++) { fputc ( fgetc ( fh_in) , fh_out) ; }

// write ALL new mhia entries to fh_out (for master library)

// copy to mhli_state[O ] .offset_entries for(i = ftell(fh_in); i < st->offset_entries; i++) { fputc ( fgetc ( fh_in) , fh out) ; }

// insert new albums for(i = 0; i < status .new_albums ; i++) {

// write new mhba to fh_out album = album_list[ i] ;

// make sure we've set everything before, like byte length fwrite(album->mhba, 0x94, 1, fh_out); // mhba_header_bytes = 0x94

// write new mhia entries to fh_out ' j = album->nitems ; for(k = 0; k < j ; k++) { artworkdb_write_mhia(fh_in, fh_out, album->items[k] ) ; }

return(O) ;

* write mh£i to fh_out; return number of bytes in new mhfi * uint32 artworkdb_wrItBjHhIf(FILE *fh_in, PILE *fh_out r artworkdb_image *image r uint32 th_id) { uint32 mhif_header_bytes = 0x7C; uint32 i, k; uint8 *tag = (uint8 *)"£iϊuτi";

uintβ bυ£[4];

// mhif ipodio_set_uintn(bu£, 0, tag, 4);

£write(buf, 1, 4, £h_out);

// mhif header size i - mhif_header_bytes; ipodio_set_uintn(bu£, 0, Si, 4); fwrite(buf, 1, 4, fh_out);

// mhif total size i = mhif_header_bytes; ipodio_set_uintn(buf , 0, &i, 4); fwrite(buf, 1, 4, fh_out);

// always 0? i = 0x0; ipodio_set_uintn(buf , 0, ai, 4); fwrite(buf, 1, 4, fh_out);

// correlation id i = th_id; // 1016, 1017, etc. ipodio_set_uintn(buf, 0, &i, 4); fwrite(bu£ r 1, 4, fh_out);

// size of image in bytes i = artworkdb_get_image_bytes(th_id) ; ipodio_sefc_uintn(bu£, 0, &i, 4); fwrite(buf, 1, 4, fh_out); for(i = 24; i < mhif_header_bytes; i++) { fwrite("\0", 1, 1, £h_out); } return (mhif_header_byteB) ; }

* write mhl£ and children to fh_out; return number of bytes added to mhfl length * uint32 artworkdb_write_mhlf(FILE *fh_in, FILE *fh_out, uint32 index) { uint32 i, k, j, n, nbytes_add = 0; state *st; artworkdb_image *image; uint8 *tag = (uintδ *)"£lhm"; uintB bu£[4]; st = S (mhli_state[ index]) j k = (status . db_rnode == ' db_photo) ? photodb_nmhfi : artworkdb_nmhfi; // photodb - 4 mhod (try

// copy to mhli_state[O] .offset for(i = ftell(fh_in) ; i < st->offset; i++) {

fputc ( fgetc ( fh_in) , fh_out) ;

}

// update mhli siεe = number of mhii entrxes, not byte length i = st->length + status.new_entrxes * k; // k mhxf copies per new mhxi ipodio_set_uintn(buf , 0, Gi, 4); fwrxte<buf, 1, 4, fh_out); fseek( fh_in, 4 , SEEK-CUR) ; /7 skip what we 3 11st updated

// copy to mhli_3tate[0J .offset_entries for(i = ftell(fh_in); i < st->offset_entries; x++) { fputc(fgetc(rh_in), fh_out); } for(j = 0; 3 < status.new_entrxes; ]++) { image = image_list[]] ;

// now write out new mhif entries for(n = 0; n < k; n++> { nbytes_add += artworkdb_write_mhif ( fh_iπ, fh_out, image, artworkdb_get_image_type(n)

} } return(nbytes_add) j

}

* write mhii and children to fh_out; return number of bytes added to mhii length * uint32 artworkdb_wrrte_πιhli(FII,E *fh_in, FILE *fh_out, uint32 index) { // mhlf or mhli uint32 x, k, 3, nbytes, nbytes_add = 0; state *st; artworkdb_tmage *image? uxntβ bu£[4]; st = s(mhl-._state[index] ) ;

// copy to mhli_state[Q] .offset £or(i = £bell(fh_in); 1 < st->offset; i++) { fputc(fgetc(fh_in) r fh_out) ;

}

// update tmhli size = number of mhii entries, not byte length i = st->Length + status.new_entries, xpodio_set_uintn(buf , 0, si, 4);

£write(buf7 1, 4, fh_out); fseek(fh_in, 4 r SEEK-CUR); // skip what we ^ust updated

// copy to mhli_state[0] .offset_entries for(i = ftell(fh in) ; i < st->olfset_entries ; x++) { fputc(fgetc(fh_in), fh_out); }

// write the mhod2 and mhni entrxes: k = ( status . db_mode == db_photo) ? photodb_nmhfi : artworkdb_nmhfx; // photodb - 4 mhod (try

for(j = 0; j < status.new_entries; j++) { image = image_list[ j ] ; // now write out new mhii entries

£write(image->mhii, 1, image->mhii_length r fh_out); nbytes_add += image->mhii_length; for(i = 0; i < k; i++) { // write mhod2>mhni>mhod3 nbytes_add += nbytes = image->mhod_lengths [ i] ; fwrite ( image->mhod[ i ] , 1 , nbytes, £h_out ) ; nbytes_add += nbytes = image->mhtii_lβngths[i] ? fwrite(iinage->mhni[i] , 1, nbytes / £h_out);

return(rtbytes_add) ;

*

* write mhsd and children to £h_out; return number of bytes added to mhsd length * uint32 artworkdb_write_mhsd(FILE *fh_in, FILE *fh_out, uint32 index) { uint32 i, nbytes, nbytes_add = 0, fpos_pre, fpos_post; state *st, *st_mhli; uint8 buf[4]; st = &(mhsd_state[index] );

// copy to mhsd_state[0] .offset for(i = ftβll(£h_in) ; i < st->offset; i++) { fputc (fgetc(fh_in) , fh_out) ; > £pos_pre = ftell(£h_out) ; if(st->type == mhsd_type_images ) { nbytes_add += artworkdb_write_mhli(fh_in, fh_out, index);

} /* else if(st->type == Jtιhsd_type_files) { nbytes_add += artworkdb_writβ_mhlf (fh_in r fh_out, index)?

} else if (st->type == mhsd_type_albums ) ■£ nbytes_add += artworkdb_write_mhla(fh_in r fh_out, index);

} else { printf("unrecognized MHSD type\n"); }*/ if (nbytes_add 1= 0) { fposjpost = £tell(fh_out);

// backtrack update mhsd size fseeX(fh_out, fpos_ρre, SEEK_SET); i = st->length + nbytes_add;

ipodio_sat_uintn(buf , 0, &i, 4 ) ; fwrite (buf , 1 , 4 , £h_out ) ; fseek( fh_out, fpos_post , SEEK_SET) ; // back to the SEEK-EWD } return ( nbytes_add) ;

* initialize some properties

uint32 artworkdb_init ( ) / \ uintlβ endian = 0x0001 status.uniqueid = 0; status.new entries = 0; status.new_albums 0? status .iρod_type = IPOD_GEN4 ; // 1 = GEN4, 2 = KANO, 4 = GEN5 status.db mode = db_photo; // db_artwork, db_photo status. flO17_ithmb = 0; status. f1016_ithmb = 0? status. flO15_ithmb = 0; status. fl009_ithmb = 0; status.flO19_ithmb = Of status.f1020 ithmb = 0;

// determine the endian-ness of the system big_endian = (*(uint8 *)Sendian == 0x01) ? 0 : 1; return(0 ) ;

*

* enter here * int main{int argc, char** argv) { char ch; uint32 i, nbytes, j, k r nbytes_add = 0, fpos;

PILE *fh, *fh_out; artworkdb_image *image; uint8 *mhii; uint8 buf[4]; artworkdb_init( ) ? if (status.dbjnode) { fh = fopen( "PhotoDB_samples/gen4/Photo Database" , "rb" ) ; // fh = fopen("photodbjmacito" , "rb" ) ;

} else {

// fh = fopen("ArtwσrkDB_samples/nano/ftrtworkDB" r "rb" ) ; // fh = fopen( "ArtworkDB_samples/video/ArtworkDB", "rb" ) ; // fh = £open( "ArtworkDB_blank" , "rb") ; //_ff0Off_w56_h28" , "rb" ) ; fh = fopen ( " ArtworkDB_out" , "rb" ) ;

> artworkdb_read_mhfd(fh) ; return(0 ) ; image = ( artworkdb_image * )calloc(sizeo£(artworkdb_image) , 1); image->attributes.uniqueid = status. uniqueid; image->attributes.dbid = 0x1; image->att.ributes.nbytes_original = 26364; image->f1016. string = (uintβ *) " :F9016_l . ithmb" ; image->f 1016.padding_top = 0x0; image->f1016.padding_left = 0x0; image->f1016.height = 140; image->f1016.width = 140; image->£1017.string = (uintδ *)" :P9017_l . ithmb" ; image->f1017.padding_top = 0x0; image->f1017.padding_left = 0x0; image->f1017.height = 56; image->f1017.width = 56; image_list[status.new_eπtries] = image; status .new_entries++; image->mhii_length = artwork.db_new_mhii(&mhii) ; image->mhii = mhii; rewind(fh); fh_out = fopen( "ArtworkDB_αut" , "wb" ) ;

// update next id for mhii - mhfd_state.o£fset_count for(i = ftell(fh); i < mhfd_state.offset_count; i++) { fputc(fgetc(fh), fh_out); >

// update next unique id i = status.uniqueid; ipodio_set_uintn(buf, 0, Si, 4); fwrite{buf, 1, 4, fh_out); fseek(fh, 4, SEEK_CUR); // skip what we just updated for(k = 0; k < 3; k++) { nbytes_add += artworkdb_write_mhsd(fh, fh_out, k); } if (nbytes_add != 0) {

// backtrack to update byte size of mhfd fpos = ftell(fh_out) ; fseek(fh_out, mhfd_state.offset, SKEK_SET) ;

// update mhfd size i = mhfd_state. length 4- nbytes_add;

ipodio_set_uintn(buf , Q, Sri, 4); fwrite(buf, 1, 4, fh_put);

Il pick up where we Left off fseek(fh_out, fpos, SEEK_SET); }

// resume copying and finish while(l) { ch = fgetc(fh); if(feof(fh)) { break; } else { fputc (ch, fh_out) ; } }

// done

£close(£h_ρut) ; fclose(fh); k = ( status.db_mode == db_photo) ? photodb_nπ_tιni : artwockdb_nmhni; for(i = 0; i < status.new_entries; i++) { image = image_list[i] ;

// free memory free ( image->πιhii ) ; for ( j = 0 ; j < k; j++ ) { free ( image->mhod[ j ] ) ; free ( image->mhni [ 3 ] ) ;

} free ( image ) ; } return( O ) ;

#ifdef cplusplus eKtern "C" } #endif

//

// 192x240 = 0.8 140/120 = 1.1111 -> 14 56/50 = 1.12 -> 5

// 1017 = thumbnail (56x56), 1016 = larger thumbnail (140x140)

// from hex dump

// 00F8 = ffOOOO

// G/B B R R/G

// 0 0 F 8 =

// 000/0 0000 1111 1/000

//

//

// 1FF8 = ffOOff (purple)

// G/B B R R/G

// 1 F F δ

// 000/1 1111 1111 1/000

//

// B F F E

// 101/1 1111 1111 1/110

//

// 7 9 C E

// 011/1 1001 1100 1/110