Ejemplo n.º 1
0
static int
write_mhli (Itdb_DB *db, iPodBuffer *buffer )
{
	GList *it = NULL;
	MhliHeader *mhli;
	unsigned int total_bytes;
	int num_thumbs;

	mhli = (MhliHeader *)init_header (buffer, "mhli", sizeof (MhliHeader));
	if (mhli == NULL) {
		return -1;
	}

	num_thumbs = 0;
	total_bytes = get_gint32 (mhli->header_len, buffer->byte_order);
	switch (buffer->db_type) {
	case DB_TYPE_PHOTO:
		it = db_get_photodb(db)->photos;
		break;
	case DB_TYPE_ITUNES:
		it = db_get_itunesdb(db)->tracks;
		break;
	default:
	        g_return_val_if_reached (-1);
	}
	while (it != NULL) {
		Itdb_Track *song;
		int bytes_written;
		iPodBuffer *sub_buffer;
		if (buffer->db_type == DB_TYPE_ITUNES) {
			song = (Itdb_Track*)it->data;
			if (!song->artwork->thumbnail || (song->artwork->dbid == 0)) {
				it = it->next;
				continue;
			}
		}
		sub_buffer = ipod_buffer_get_sub_buffer (buffer, total_bytes);
		if (sub_buffer == NULL) {
			break;
		}
		bytes_written = write_mhii (db, it->data, sub_buffer);
		ipod_buffer_destroy (sub_buffer);
		if (bytes_written != -1) {
			num_thumbs++;
			total_bytes += bytes_written;
		}
		it = it->next;
	}
	mhli = ipod_buffer_get_pointer (buffer);
	mhli->num_children = get_gint32 (num_thumbs, buffer->byte_order);
	dump_mhl ((MhlHeader *)mhli, "mhli");

	return total_bytes;
}
Ejemplo n.º 2
0
static void *
init_header (iPodBuffer *buffer, gchar _header_id[4], guint header_len)
{
	MHeader *mh;
	int padded_size;
	gchar *header_id;

	padded_size = get_padded_header_size (_header_id);
	if (padded_size != 0) {
		header_len = padded_size;
	}
	g_assert (header_len > sizeof (MHeader));
	ipod_buffer_maybe_grow (buffer, header_len);

	mh = (MHeader*)ipod_buffer_get_pointer (buffer);
	if (mh == NULL) {
		return NULL;
	}
	memset (mh, 0, header_len);

	header_id = g_strndup (_header_id, 4);
	if (buffer->byte_order == G_BIG_ENDIAN) {
		g_strreverse (header_id);
	}
	strncpy ((char *)mh->header_id, header_id, 4);
	mh->header_len = get_gint32 (header_len, buffer->byte_order);

	g_free (header_id);
	return mh;
}
Ejemplo n.º 3
0
static guchar *
unpack_RGB_888 (guint16 *pixels, guint bytes_len, guint byte_order)
{
	guchar *result;
	guint i;
	guint32 *pixels32;

	result = g_malloc ((bytes_len/4) * 3);

	pixels32 = (guint32 *)pixels;

	for (i = 0; i < bytes_len/4; i++) {
		guint32 cur_pixel;
		/* FIXME: endianness */
		cur_pixel = get_gint32 (pixels32[i], byte_order);
		/* Unpack pixels */
		result[3*i] = (cur_pixel & RED_MASK_888) >> RED_SHIFT_888;
		result[3*i+1] = (cur_pixel & GREEN_MASK_888) >> GREEN_SHIFT_888;
		result[3*i+2] = (cur_pixel & BLUE_MASK_888) >> BLUE_SHIFT_888;

		/* Normalize color values so that they use a [0..255] range */
		/* (not necessary for 888 encoding) */
/* 		result[3*i] <<= (8 - RED_BITS_888); */
/* 		result[3*i+1] <<= (8 - GREEN_BITS_888); */
/* 		result[3*i+2] <<= (8 - BLUE_BITS_888); */
	}

	return result;
}
Ejemplo n.º 4
0
static guchar *
unpack_experimental (guint16 *pixels, guint bytes_len, guint byte_order,
		     gint width, gint height)
{
	guchar *result;
	guint i;
	guint32 *rpixels;

	g_return_val_if_fail (bytes_len < (G_MAXUINT/3), NULL);

	result = g_malloc ((bytes_len/4) * 3);

	rpixels = (guint32 *)pixels;

	for (i = 0; i < bytes_len/4; i++) {
		guint32 cur_pixel;
		/* FIXME: endianness */
		cur_pixel = get_gint32 (rpixels[i], byte_order);
printf ("%8x\n", cur_pixel);
		/* Unpack pixels */
		result[3*i] = (cur_pixel & RED_MASK_888) >> RED_SHIFT_888;
		result[3*i+1] = (cur_pixel & GREEN_MASK_888) >> GREEN_SHIFT_888;
		result[3*i+2] = (cur_pixel & BLUE_MASK_888) >> BLUE_SHIFT_888;

		/* Normalize color values so that they use a [0..255] range */
		/* (not really necessary for 888 encoding) */
/* 		result[3*i] <<= (8 - RED_BITS_888); */
/* 		result[3*i+1] <<= (8 - GREEN_BITS_888); */
/* 		result[3*i+2] <<= (8 - BLUE_BITS_888); */
	}

	return result;
}
Ejemplo n.º 5
0
static int
write_mhsd (Itdb_DB *db, iPodBuffer *buffer, enum MhsdType type)
{
	ArtworkDB_MhsdHeader *mhsd;
	unsigned int total_bytes;
	int bytes_written;
	iPodBuffer *sub_buffer;

	g_assert (type >= MHSD_TYPE_MHLI);
	g_assert (type <= MHSD_TYPE_MHLF);
	mhsd = (ArtworkDB_MhsdHeader *)init_header (buffer, "mhsd", sizeof (ArtworkDB_MhsdHeader));
	if (mhsd == NULL) {
		return -1;
	}
	total_bytes = get_gint32 (mhsd->header_len, buffer->byte_order);
	mhsd->total_len = get_gint32 (total_bytes, buffer->byte_order);
	mhsd->index = get_gint16 (type, buffer->byte_order);
	bytes_written = -1;

	sub_buffer = ipod_buffer_get_sub_buffer (buffer, total_bytes);
	if (sub_buffer == NULL) {
		return -1;
	}
	switch (type) {
	case MHSD_TYPE_MHLI:
		bytes_written = write_mhli (db, sub_buffer);
		break;
	case MHSD_TYPE_MHLA:
		bytes_written = write_mhla (db, sub_buffer);
		break;
	case MHSD_TYPE_MHLF:
		bytes_written = write_mhlf (db, sub_buffer);
		break;
	}
	ipod_buffer_destroy (sub_buffer);
	if (bytes_written == -1) {
		return -1;
	} else {
		total_bytes += bytes_written;
		mhsd = ipod_buffer_get_pointer (buffer);
		mhsd->total_len = get_gint32 (total_bytes, buffer->byte_order);
	}

	dump_mhsd (mhsd);

	return total_bytes;
}
Ejemplo n.º 6
0
static int
write_mhod_type_1 (gchar *string, iPodBuffer *buffer)
{
	ArtworkDB_MhodHeaderString *mhod;
	unsigned int total_bytes;
	int len;
	int padding;

	g_assert (string != NULL);

	total_bytes = sizeof (ArtworkDB_MhodHeaderString);
	mhod = (ArtworkDB_MhodHeaderString *)init_header (buffer, "mhod",
                                                          total_bytes);
	if (mhod == NULL) {
		return -1;
	}
	mhod->total_len = get_gint32 (total_bytes, buffer->byte_order);
	/* Modify header length, since iTunes only puts the length of
	 * MhodHeader in header_len
	 */
	mhod->header_len = get_gint32 (sizeof (ArtworkDB_MhodHeader), buffer->byte_order);
	mhod->encoding = get_gint32 (0x01, buffer->byte_order);
	len = strlen (string);
	mhod->string_len = get_gint32 (len, buffer->byte_order);

	padding = 4 - ( (total_bytes + len) % 4 );
	if (padding == 4)
	    padding = 0;
	mhod->padding_len = padding;
	mhod->type = get_gint16 (0x01, buffer->byte_order);

	/* Make sure we have enough free space to write the string */
	ipod_buffer_maybe_grow (buffer, len + padding);
	mhod = ipod_buffer_get_pointer (buffer);
	if (mhod == NULL) {
		return -1;
	}
	memcpy (mhod->string, string, len);
	total_bytes += len + padding;
	mhod->total_len = get_gint32 (total_bytes, buffer->byte_order);

	dump_mhod_string (mhod);

	return total_bytes;
}
Ejemplo n.º 7
0
void *
db_parse_context_get_m_header_internal (DBParseContext *ctx, const char *id, off_t size) 
{
	MHeader *h;
	char *header_id;
	
	if (!ctx) {
		return NULL;
	}

	if (db_parse_context_get_remaining_length (ctx) < 8) {
		return NULL;
	}

	h = (MHeader *)ctx->cur_pos;
	if (!h) {
		return NULL;
	}
	
	header_id = g_strndup ((char *)h->header_id, 4);
	if (ctx->byte_order == G_BIG_ENDIAN) {
		g_strreverse (header_id);
	}
	if (strncmp (id, header_id, 4) != 0) {
	        g_free (header_id);
		return NULL;
	}

	g_free (header_id);

	/* FIXME: this test sucks for compat: if a field is smaller than 
	 * expected, we probably should create a buffer of the appropriate 
	 * size inited to 0, copy the data that is available in it and use
	 * that buffer in the rest of the code (maybe it's harmful to have
	 * some fields at 0 in some headers though...)
	 */
	if (get_gint32 (h->header_len, ctx->byte_order) < size) {
		return NULL;
	}

	db_parse_context_set_header_len (ctx, get_gint32 (h->header_len, 
							  ctx->byte_order));

	return h;
}
Ejemplo n.º 8
0
static int
write_mhia (gint image_id, iPodBuffer *buffer)
{
	MhiaHeader *mhia;
	unsigned int total_bytes;


	mhia = (MhiaHeader *)init_header (buffer, "mhia", 40);
	if (mhia == NULL) {
		return -1;
	}

	mhia->total_len = mhia->header_len;
	mhia->image_id = get_gint32 (image_id, buffer->byte_order);
	total_bytes = get_gint32 (mhia->header_len, buffer->byte_order);
	dump_mhia( mhia );
	return total_bytes;
}
Ejemplo n.º 9
0
static int
write_mhif (Itdb_DB *db, iPodBuffer *buffer,
            const Itdb_ArtworkFormat *img_info)
{
	MhifHeader *mhif;

	mhif = (MhifHeader *)init_header (buffer, "mhif", sizeof (MhifHeader));
	if (mhif == NULL) {
		return -1;
	}
	mhif->total_len = mhif->header_len;

	mhif->format_id = get_gint32 (img_info->format_id,
		               	      buffer->byte_order);
	mhif->image_size = get_gint32 (img_info->height * img_info->width * 2,
				       buffer->byte_order);

	dump_mhif (mhif);

	return get_gint32 (mhif->header_len, buffer->byte_order);
}
Ejemplo n.º 10
0
static int
write_mhla (Itdb_DB *db, iPodBuffer *buffer)
{
	GList *it;
	MhlaHeader *mhla;
	iPodBuffer *sub_buffer;
	unsigned int total_bytes;

	mhla = (MhlaHeader *)init_header (buffer, "mhla", sizeof (MhlaHeader));
	if (mhla == NULL) {
		return -1;
	}
	total_bytes = get_gint32 (mhla->header_len, buffer->byte_order);
	if (buffer->db_type == DB_TYPE_PHOTO) {
	    unsigned int bytes_written;
            unsigned int num_children = 0;
	    for (it = db_get_photodb(db)->photoalbums; it != NULL; it = it->next) {
		Itdb_PhotoAlbum *album = (Itdb_PhotoAlbum *)it->data;

		sub_buffer = ipod_buffer_get_sub_buffer (buffer, total_bytes);
		if (sub_buffer == NULL) {
		    return -1;
		}
		bytes_written = write_mhba (album, sub_buffer);
		ipod_buffer_destroy (sub_buffer);
		if (bytes_written == -1) {
		    return -1;
		}
		total_bytes += bytes_written;
		mhla = ipod_buffer_get_pointer (buffer);
		num_children++;
		mhla->num_children = get_gint32 (num_children,
                                                 buffer->byte_order);
	    }
	}

	dump_mhl ((MhlHeader *)mhla, "mhla");

	return total_bytes;
}
Ejemplo n.º 11
0
static int
write_mhni (Itdb_DB *db, Itdb_Thumb_Ipod_Item *item, iPodBuffer *buffer)
{
	MhniHeader *mhni;
	unsigned int total_bytes;
	int bytes_written;
	iPodBuffer *sub_buffer;
        const Itdb_ArtworkFormat *format;

	if (item == NULL) {
		return -1;
	}

	mhni = (MhniHeader *)init_header (buffer, "mhni",
					  sizeof (MhniHeader));
	if (mhni == NULL) {
		return -1;
	}
	total_bytes =          get_gint32 (mhni->header_len,
					   buffer->byte_order);
	mhni->total_len =      get_gint32 (total_bytes,
					   buffer->byte_order);
        format = item->format;
	mhni->format_id = get_gint32 (format->format_id, buffer->byte_order);
	mhni->image_width =    get_gint16 (item->width, buffer->byte_order);
	mhni->image_height =   get_gint16 (item->height, buffer->byte_order);
	mhni->image_size =     get_gint32 (item->size, buffer->byte_order);
	mhni->ithmb_offset =   get_gint32 (item->offset, buffer->byte_order);
	mhni->vertical_padding = get_gint16 (item->vertical_padding,
					     buffer->byte_order);
	mhni->horizontal_padding = get_gint16 (item->horizontal_padding,
					       buffer->byte_order);

	sub_buffer = ipod_buffer_get_sub_buffer (buffer, total_bytes);
	if (sub_buffer == NULL) {
		return  -1;
	}
	bytes_written = write_mhod_type_3 (item->filename, sub_buffer);
	ipod_buffer_destroy (sub_buffer);
	if (bytes_written == -1) {
		return -1;
	}
	total_bytes += bytes_written;
	mhni = ipod_buffer_get_pointer (buffer);
	mhni->total_len = get_gint32 (total_bytes, buffer->byte_order);
	/* Only update number of children when all went well to try to get
	 * something somewhat consistent when there are errors
	 */
	mhni->num_children = get_gint32 (1, buffer->byte_order);

	dump_mhni (mhni);

	return total_bytes;
}
Ejemplo n.º 12
0
static int
write_mhod (Itdb_DB *db, Itdb_Thumb_Ipod_Item *thumb, iPodBuffer *buffer)
{
	ArtworkDB_MhodHeader *mhod;
	unsigned int total_bytes;
	int bytes_written;
	iPodBuffer *sub_buffer;

	if (thumb == NULL) {
		return -1;
	}

	mhod = (ArtworkDB_MhodHeader *)
	    init_header (buffer, "mhod",
			 sizeof (ArtworkDB_MhodHeader));
	if (mhod == NULL) {
		return -1;
	}
	total_bytes = sizeof (ArtworkDB_MhodHeader);
	mhod->total_len = get_gint32 (total_bytes, buffer->byte_order);
	mhod->type = get_gint16 (MHOD_TYPE_LOCATION, buffer->byte_order);
	sub_buffer = ipod_buffer_get_sub_buffer (buffer, total_bytes);
	if (sub_buffer == NULL) {
		return -1;
	}
	bytes_written = write_mhni (db, thumb, sub_buffer);
	ipod_buffer_destroy (sub_buffer);
	if (bytes_written == -1) {
		return -1;
	}
	total_bytes += bytes_written;
	mhod = ipod_buffer_get_pointer (buffer);
	mhod->total_len = get_gint32 (total_bytes, buffer->byte_order);

	dump_mhod (mhod);

	return total_bytes;
}
Ejemplo n.º 13
0
static int
write_mhfd (Itdb_DB *db, iPodBuffer *buffer, int id_max)
{
	MhfdHeader *mhfd;
	unsigned int total_bytes;
	int bytes_written;
	int i;

	
	mhfd = (MhfdHeader *)init_header (buffer, "mhfd", sizeof (MhfdHeader));
	if (mhfd == NULL) {
		return -1;
	}
	total_bytes = get_gint32 (mhfd->header_len, buffer->byte_order);
	mhfd->total_len = get_gint32 (total_bytes, buffer->byte_order);
	switch (buffer->db_type) {
	case DB_TYPE_PHOTO:
		mhfd->unknown2 = get_gint32 (2, buffer->byte_order);
		break;
	case DB_TYPE_ITUNES:
		mhfd->unknown2 = get_gint32 (2, buffer->byte_order);
		break;
	}
	mhfd->next_id = get_gint32 (id_max, buffer->byte_order);
	mhfd->unknown_flag1 = 2;
	for (i = 1 ; i <= 3; i++) {
		iPodBuffer *sub_buffer;

		sub_buffer = ipod_buffer_get_sub_buffer (buffer, total_bytes);
		if (sub_buffer == NULL) {
			continue;
		}
		bytes_written = write_mhsd (db, sub_buffer, i);
		ipod_buffer_destroy (sub_buffer);
		if (bytes_written == -1) {
			return -1;
		}
		total_bytes += bytes_written;
		mhfd = ipod_buffer_get_pointer (buffer);
		mhfd->total_len = get_gint32 (total_bytes, buffer->byte_order);
		mhfd->num_children = get_gint32 (i, buffer->byte_order);
	}

	dump_mhfd (mhfd);

	return total_bytes;
}
Ejemplo n.º 14
0
static int
write_mhii (Itdb_DB *db, void *data, iPodBuffer *buffer)
{
	MhiiHeader *mhii;
	unsigned int total_bytes;
	int bytes_written;
	int num_children;
	const GList *it = NULL;
	Itdb_Track *song;
	Itdb_Artwork *artwork;
	guint64 mactime;
	Itdb_Device *device = db_get_device (db);

	mhii = (MhiiHeader *)init_header (buffer, "mhii", sizeof (MhiiHeader));
	if (mhii == NULL) {
		return -1;
	}
	total_bytes = get_gint32 (mhii->header_len, buffer->byte_order);

	switch( buffer->db_type) {
	case DB_TYPE_ITUNES:
		song = (Itdb_Track *)data;
		artwork = song->artwork;
		mhii->song_id = get_gint64 (song->dbid, buffer->byte_order);
		break;
	case DB_TYPE_PHOTO:
		artwork = (Itdb_Artwork *)data;
		mhii->song_id = get_gint64 (artwork->id + 2, buffer->byte_order);
		break;
	default:
	        g_return_val_if_reached (-1);
	}
	mhii->image_id = get_guint32 (artwork->id, buffer->byte_order);
	mhii->unknown4 = get_gint32 (artwork->unk028, buffer->byte_order);
	mhii->rating = get_gint32 (artwork->rating, buffer->byte_order);
	mhii->unknown6 = get_gint32 (artwork->unk036, buffer->byte_order);

	mactime = device_time_time_t_to_mac (device, artwork->creation_date);
	mhii->orig_date = get_guint32 (mactime, buffer->byte_order);

	mactime = device_time_time_t_to_mac (device, artwork->digitized_date);
	mhii->digitized_date = get_guint32 (mactime, buffer->byte_order);

	mhii->orig_img_size = get_gint32 (artwork->artwork_size, buffer->byte_order);
	num_children = 0;
        /* Before trying to write the artwork or photo database, the ithmb
         * files have been written, which will have converted all thumbnails 
         * attached to the tracks to ITDB_THUMB_TYPE_IPOD thumbnails.
         */
        g_assert (artwork->thumbnail->data_type == ITDB_THUMB_TYPE_IPOD);
	for (it=itdb_thumb_ipod_get_thumbs ((Itdb_Thumb_Ipod *)artwork->thumbnail); 
             it!=NULL; 
             it=it->next)
	{
		iPodBuffer *sub_buffer;
		Itdb_Thumb_Ipod_Item *thumb;

                thumb = (Itdb_Thumb_Ipod_Item *)it->data;
                if (thumb->format == NULL) {
		    /* skip this thumb */
		    continue;
		}

		mhii->num_children = get_gint32 (num_children,
						 buffer->byte_order);
		mhii->total_len = get_gint32 (total_bytes, buffer->byte_order);
		sub_buffer = ipod_buffer_get_sub_buffer (buffer, total_bytes);
		if (sub_buffer == NULL) {
			return -1;
		}
		bytes_written = write_mhod (db, thumb, sub_buffer);
		ipod_buffer_destroy (sub_buffer);
		if (bytes_written == -1) {
			return -1;
		}
		total_bytes += bytes_written;
		mhii = ipod_buffer_get_pointer (buffer);
		num_children++;
	}

	mhii->num_children = get_gint32 (num_children, buffer->byte_order);
	mhii->total_len = get_gint32 (total_bytes, buffer->byte_order);

	dump_mhii (mhii);

	return total_bytes;
}
Ejemplo n.º 15
0
static int
write_mhlf (Itdb_DB *db, iPodBuffer *buffer)
{
	MhlfHeader *mhlf;
	unsigned int total_bytes;
	int bytes_written;
        GList *formats; 
        GList *it;
        unsigned int num_children;

	mhlf = (MhlfHeader *)init_header (buffer, "mhlf", sizeof (MhlfHeader));
	if (mhlf == NULL) {
		return -1;
	}

	total_bytes = get_gint32 (mhlf->header_len, buffer->byte_order);
        num_children = 0;
        mhlf->num_files = get_gint32 (num_children, buffer->byte_order);

        formats = NULL;
        switch (buffer->db_type) {
        case DB_TYPE_ITUNES:
            formats = itdb_device_get_cover_art_formats(db_get_device(db));
            break;
	case DB_TYPE_PHOTO:
            formats = itdb_device_get_photo_formats(db_get_device(db));
            break;
        }
        if (formats == NULL) {
                return total_bytes;
        }

        for (it = formats; it != NULL; it = it->next) {
                const Itdb_ArtworkFormat *format;
	        iPodBuffer *sub_buffer;
                
                format = (const Itdb_ArtworkFormat *)it->data;
        	sub_buffer = ipod_buffer_get_sub_buffer (buffer, total_bytes);
        	if (sub_buffer == NULL) {
                        g_list_free (formats);
        		return -1;
        	}

        	bytes_written = write_mhif (db, sub_buffer, format);
	        			    
        	ipod_buffer_destroy (sub_buffer);
        	if (bytes_written == -1) {
        		return -1;
        	}
        	total_bytes += bytes_written;
		mhlf = ipod_buffer_get_pointer (buffer);

                num_children++;
        	/* Only update number of children when all went well to try 
                 * to get something somewhat consistent when there are errors
        	 */
        	mhlf->num_files = get_gint32 (num_children, buffer->byte_order);
        }
	dump_mhl ((MhlHeader *)mhlf, "mhlf");
        g_list_free (formats);

	return total_bytes;
}
Ejemplo n.º 16
0
static int
write_mhod_type_3 (gchar *string, iPodBuffer *buffer)
{
	ArtworkDB_MhodHeaderString *mhod;
	unsigned int total_bytes;
	glong len;
	const gint g2l = sizeof (gunichar2);
	gunichar2 *utf16, *strp;
	int i, padding;

	g_assert (string != NULL);

	total_bytes = sizeof (ArtworkDB_MhodHeaderString);
	mhod = (ArtworkDB_MhodHeaderString *) init_header (buffer, "mhod", 
                                                           total_bytes);
	if (mhod == NULL) {
		return -1;
	}
	mhod->total_len = get_gint32 (total_bytes, buffer->byte_order);
	/* Modify header length, since iTunes only puts the length of
	 * MhodHeader in header_len
	 */
	mhod->header_len = get_gint32 (sizeof (ArtworkDB_MhodHeader),
				       buffer->byte_order);
	mhod->type = get_gint16 (3, buffer->byte_order);

	/* FIXME: Tidy this up, combine cases more */
	/* Some magic: endianess-reversed (BE) mobile phones use UTF8
	 * (version 1) with padding, standard iPods (LE) use UTF16
	 * (version 2).*/
	switch (buffer->byte_order)
	{
	case G_LITTLE_ENDIAN:
	    utf16 = g_utf8_to_utf16 (string, -1, NULL, &len, NULL);
	    if (utf16 == NULL) {
		return -1;
	    }

	    mhod->encoding = 2; /* 8 bit field, no need to byteswap */

	    /* number of bytes of the string encoded in UTF-16 */
	    mhod->string_len = get_gint32 (g2l * len, buffer->byte_order);
	    padding = 4 - ( (total_bytes + g2l*len) % 4 );
	    if (padding == 4)
		padding = 0;
	    mhod->padding_len = padding; /* 8 bit field, no need to byteswap */

 	    total_bytes += g2l*len + padding;

	    /* Make sure we have enough free space to write the string */
	    ipod_buffer_maybe_grow (buffer, g2l*len + padding);
	    mhod = ipod_buffer_get_pointer (buffer);
	    if (mhod == NULL) {
		    g_free (utf16);
		    return  -1;
	    }
	    strp = (gunichar2 *)mhod->string;
	    for (i = 0; i < len; i++) {
		strp[i] = get_gint16 (utf16[i], buffer->byte_order);
	    }
	    g_free (utf16);
	    memset (mhod->string + g2l*len, 0, padding);
	    break;
	case G_BIG_ENDIAN:
	    mhod->encoding = 1; /* 8 bit field, no need to byteswap */
            /* FIXME: len isn't initialized */
	    mhod->string_len = get_gint32 (len, buffer->byte_order);
	    /* pad string if necessary */
	    /* e.g. len = 7 bytes, len%4 = 3, 4-3=1 -> requires 1 byte
	       padding */
	    padding = 4 - ( (total_bytes + len) % 4 );
	    if (padding == 4)
		padding = 0;
	    mhod->padding_len = padding; /* 8 bit field, no need to byteswap */

	    /* Make sure we have enough free space to write the string */
	    ipod_buffer_maybe_grow (buffer, len+padding);
	    mhod = ipod_buffer_get_pointer (buffer);
	    if (mhod == NULL) {
		    return -1;
	    }
	    memcpy (mhod->string, string, len);
	    memset (mhod->string + len, 0, padding);
	    total_bytes += (len+padding);
	}
	mhod->total_len = get_gint32 (total_bytes, buffer->byte_order);

	dump_mhod_string (mhod);

	return total_bytes;
}
Ejemplo n.º 17
0
static int
write_mhba (Itdb_PhotoAlbum *album, iPodBuffer *buffer)
{
	GList *it;
	MhbaHeader *mhba;
	iPodBuffer *sub_buffer;
	unsigned int total_bytes;
	unsigned int bytes_written;

	mhba = (MhbaHeader *)init_header (buffer, "mhba", sizeof (MhbaHeader));
	if (mhba == NULL) {
		return -1;
	}
	mhba->num_mhods = get_gint32(1, buffer->byte_order);
	mhba->num_mhias = get_gint32(g_list_length (album->members),
				     buffer->byte_order);
	mhba->album_id = get_gint32(album->album_id, buffer->byte_order);
	mhba->unk024 = get_gint32(album->unk024, buffer->byte_order);
	mhba->unk028 = get_gint16(album->unk028, buffer->byte_order);
	mhba->album_type = album->album_type;
	mhba->playmusic = album->playmusic;
	mhba->repeat = album->repeat;
	mhba->random = album->random;
	mhba->show_titles = album->show_titles;
	mhba->transition_direction = album->transition_direction;
	mhba->slide_duration = get_gint32(album->slide_duration,
					  buffer->byte_order);
	mhba->transition_duration = get_gint32(album->transition_duration,
					       buffer->byte_order);
	mhba->unk044 = get_gint32(album->unk044, buffer->byte_order);
	mhba->unk048 = get_gint32(album->unk048, buffer->byte_order);
	mhba->song_id = get_gint64(album->song_id, buffer->byte_order);
	mhba->prev_album_id = get_gint32(album->prev_album_id,
					 buffer->byte_order);

	total_bytes = get_gint32 (mhba->header_len, buffer->byte_order);

	/* FIXME: Write other mhods */
	/* Write album title */
	sub_buffer = ipod_buffer_get_sub_buffer (buffer, total_bytes);
	if (sub_buffer == NULL) {
	    return -1;
	}
	bytes_written = write_mhod_type_1 (album->name, sub_buffer);
	ipod_buffer_destroy (sub_buffer);
	if (bytes_written == -1) {
	    return -1;
	}
	total_bytes += bytes_written;

	for (it = album->members; it != NULL; it = it->next) {
	        Itdb_Artwork *photo = it->data;
		g_return_val_if_fail (photo, -1);

		sub_buffer = ipod_buffer_get_sub_buffer (buffer, total_bytes);
		if (sub_buffer == NULL) {
		    return -1;
		}
		bytes_written = write_mhia (photo->id, sub_buffer);
		ipod_buffer_destroy (sub_buffer);
		if (bytes_written == -1) {
		    return -1;
		}
		total_bytes += bytes_written;
	}
	mhba = ipod_buffer_get_pointer (buffer);
	mhba->total_len = get_gint32( total_bytes, buffer->byte_order );
	dump_mhba ( mhba );
	return total_bytes;
}