/* Read some data from the mp3 file stream */ static unsigned mp3_read_data(unsigned channel, unsigned char* data, unsigned max) { unsigned run; if (mixer_map[channel].pos == mixer_map[channel].end) return 0; run = max; if (mixer_map[channel].pos + run > mixer_map[channel].end) run = mixer_map[channel].end - mixer_map[channel].pos; if (!run) return 0; if (mixer_map[channel].file) { if (fzread(data, run, 1, mixer_map[channel].file)!=1) { mixer_channel_abort(channel); return 0; } } else { memcpy(data, mixer_map[channel].data + mixer_map[channel].pos, run); } mixer_map[channel].pos += run; mixer_channel_loop_check(channel); return run; }
static adv_error wave_read_tag(adv_fz* f, char* tag) { if (fzread(tag, 4, 1, f) != 1) return -1; return 0; }
adv_error le_uint32_fzread(adv_fz* f, unsigned* v) { unsigned char p[4]; if (fzread(p, 4, 1, f) != 1) return -1; *v = le_uint32_read(p); return 0; }
adv_error le_uint16_fzread(adv_fz* f, unsigned* v) { unsigned char p[2]; if (fzread(p, 2, 1, f) != 1) return -1; *v = le_uint16_read(p); return 0; }
static adv_error wave_skip(adv_fz* f, unsigned num) { unsigned count = 0; while (count<num) { char ch; if (fzread(&ch, 1, 1, f) != 1) return -1; ++count; } return 0; }
UINT32 osd_fread(osd_file* file, void* buffer, UINT32 length) { adv_fz* h = (adv_fz*)file; UINT32 r; r = fzread(buffer, 1, length, h); log_debug(("osd: osd_fread(%p, length:%d) -> %d\n", file, (int)length, (int)r)); return r; }
/** * Read a char from the file. * The semantic is like the C fgetc() function. * It assume to read a binary file without any "\r", "\n" conversion. */ int fzgetc(adv_fz* f) { if (f->type == fz_file) { return fgetc_lock(f->f); } else { unsigned char r; if (fzread(&r, 1, 1, f)==1) return r; else return EOF; } }
static adv_error pcx_header_read(adv_fz* fz, struct pcx_header_t* header) { if (le_uint8_fzread(fz, &header->manufacturer) != 0) return -1; if (le_uint8_fzread(fz, &header->version) != 0) return -1; if (le_uint8_fzread(fz, &header->encoding) != 0) return -1; if (le_uint8_fzread(fz, &header->bits_per_pixel) != 0) return -1; if (le_uint16_fzread(fz, &header->x_min) != 0) return -1; if (le_uint16_fzread(fz, &header->y_min) != 0) return -1; if (le_uint16_fzread(fz, &header->x_max) != 0) return -1; if (le_uint16_fzread(fz, &header->y_max) != 0) return -1; if (le_uint16_fzread(fz, &header->hdpi) != 0) return -1; if (le_uint16_fzread(fz, &header->vdpi) != 0) return -1; if (fzread(&header->colornmap, 48, 1, fz) != 1) return -1; if (le_uint8_fzread(fz, &header->reserved) != 0) return -1; if (le_uint8_fzread(fz, &header->planes) != 0) return -1; if (le_uint16_fzread(fz, &header->bytes_per_line) != 0) return -1; if (le_uint16_fzread(fz, &header->palette_info) != 0) return -1; if (le_uint16_fzread(fz, &header->h_screen_size) != 0) return -1; if (le_uint16_fzread(fz, &header->v_screen_size) != 0) return -1; if (fzread(&header->filler, 54, 1, fz) != 1) return -1; return 0; }
/** * Read the MNG file signature. * \param f File to read. */ adv_error adv_mng_read_signature(adv_fz* f) { unsigned char signature[8]; if (fzread(signature, 8, 1, f) != 1) { error_set("Error reading the signature"); return -1; } if (memcmp(signature, MNG_Signature, 8)!=0) { error_set("Invalid MNG signature"); return -1; } return 0; }
/** * Seek to an arbitrary position. * The semantic is like the C fseek() function. */ adv_error fzseek(adv_fz* f, long offset, int mode) { if (f->type == fz_file) { switch (mode) { case SEEK_SET : return fseek(f->f, f->real_offset + offset, SEEK_SET); case SEEK_CUR : return fseek(f->f, offset, SEEK_CUR); case SEEK_END : if (f->real_size) return fseek(f->f, f->real_size - offset, SEEK_SET); else return fseek(f->f, offset, SEEK_END); default: return -1; } } else { int pos; switch (mode) { case SEEK_SET : pos = offset; break; case SEEK_CUR : pos = f->virtual_pos + offset; break; case SEEK_END : pos = f->virtual_size - offset; break; default: return -1; } if (pos < 0 || pos > f->virtual_size) return -1; if (f->type == fz_memory_read) { f->virtual_pos = pos; return 0; } else if (f->type == fz_memory_write) { if (fzgrow(f, pos) != 0) return -1; f->virtual_pos = pos; return 0; } else if (f->type == fz_file_part) { if (fseek(f->f, f->real_offset + f->virtual_pos, SEEK_SET) != 0) return -1; f->virtual_pos = pos; return 0; } else if (f->type == fz_file_compressed) { unsigned offset; if (pos < f->virtual_pos) { /* if backward reopen the file */ int err; compressed_done(f); err = fseek(f->f, f->real_offset, SEEK_SET); f->virtual_pos = 0; compressed_init(f); if (err != 0) return -1; } /* data to read */ offset = pos - f->virtual_pos; /* read all the data */ while (offset > 0) { unsigned char buffer[256]; unsigned run = offset; if (run > 256) run = 256; if (fzread(buffer, run, 1, f) != 1) return -1; offset -= run; } return 0; } else { return -1; } } }
static adv_error mixer_raw_pump(unsigned channel) { unsigned nmin; unsigned nmax; unsigned run; unsigned sample_size; unsigned char data[MIXER_PAGE_SIZE]; if (mixer_channel_input_is_empty(channel)) return -1; mixer_channel_need(channel, &nmin, &nmax); /* no need */ if (nmin == 0) return -1; sample_size = 4; if (mixer_map[channel].nchannel == 1) sample_size /= 2; if (mixer_map[channel].bit == 8) sample_size /= 2; nmin *= sample_size; nmax *= sample_size; run = nmin; if (mixer_map[channel].pos + run > mixer_map[channel].end) run = mixer_map[channel].end - mixer_map[channel].pos; if (run > MIXER_PAGE_SIZE) run = MIXER_PAGE_SIZE; assert(run % sample_size == 0); if (run) { if (mixer_map[channel].file) { if (fzread(data, run, 1, mixer_map[channel].file) != 1) { mixer_channel_abort(channel); return -1; } mixer_channel_mix(channel, data, run / sample_size); } else { mixer_channel_mix(channel, mixer_map[channel].data + mixer_map[channel].pos, run / sample_size); } } mixer_map[channel].pos += run; mixer_channel_loop_check(channel); /* check for the end of the stream */ if (mixer_map[channel].pos == mixer_map[channel].end && !mixer_map[channel].loop) { mixer_map[channel].empty = 1; } if (!run) return -1; return 0; }
/** * Load a .ico file in a bitmap. * Only the 16 and 256 color formats are supported. * \param f File to load. * \param rgb Where to put the palette information. it must point to a vector of 256 elements. * \param rgb_max Where to put the number of palette entries. * \param bitmap_mask Where to put the mask bitmap. * \return The loaded bitmap or 0 on error. */ adv_bitmap* adv_bitmap_load_icon(adv_color_rgb* rgb, unsigned* rgb_max, adv_bitmap** bitmap_mask, adv_fz* f) { adv_bitmap* bitmap; struct icon_header_t header; struct icon_entry_t* entry; int i; if (icon_header_read(f, &header) != 0) goto out; if (header.reserved != 0) goto out; if (header.type != 1) goto out; if (header.count < 1) goto out; entry = malloc(header.count * sizeof(struct icon_entry_t)); if (!entry) goto out; for(i=0;i<header.count;++i) { if (icon_entry_read(f, entry + i)!=0) goto out_entry; } for(i=0;i<header.count;++i) { struct icon_bitmap_header_t bitmap_header; unsigned j, y; unsigned colors; if (entry[i].color == 0) { colors = 256; if (entry[i].bit != 8 && entry[i].bit != 0) /* 0 is out of standard but acceptable */ continue; /* unsupported */ } else if (entry[i].color == 16) { colors = 16; if (entry[i].bit != 4 && entry[i].bit != 0) /* 0 is out of standard but acceptable */ continue; /* unsupported */ } else { continue; /* unsupported */ } if (entry[i].planes != 1 && entry[i].planes != 0) /* 0 is out of standard but acceptable */ continue; /* unsupported */ if (fzseek(f, entry[i].offset, SEEK_SET)!=0) goto out_entry; if (icon_bitmap_header_read(f, &bitmap_header) != 0) goto out_entry; if (colors == 256) { if (bitmap_header.bit != 8) continue; /* unsupported */ } else if (colors == 16) { if (bitmap_header.bit != 4) continue; /* unsupported */ } if (bitmap_header.planes != 1) continue; /* unsupported */ if (bitmap_header.compression != 0) continue; /* unsupported */ for(j=0;j<colors;++j) { struct icon_rgb_t color; if (icon_rgb_read(f, &color) != 0) goto out_entry; rgb[j].red = color.red; rgb[j].green = color.green; rgb[j].blue = color.blue; } *rgb_max = colors; bitmap = adv_bitmap_alloc(entry[i].width, entry[i].height, 1); if (!bitmap) goto out_entry; *bitmap_mask = adv_bitmap_alloc(entry[i].width, entry[i].height, 1); if (!*bitmap_mask) goto out_bitmap; if (colors == 256) { /* read bitmap xor data (8 bit per pixel) */ for(y=0;y<bitmap->size_y;++y) { unsigned char* line = adv_bitmap_line(bitmap, bitmap->size_y - y - 1); if (fzread(line, bitmap->size_x*bitmap->bytes_per_pixel, 1, f)!=1) goto out_bitmap_mask; } } else if (colors == 16) { /* read bitmap xor data (4 bit per pixel) */ for(y=0;y<bitmap->size_y;++y) { int k; unsigned char* line = adv_bitmap_line(bitmap, bitmap->size_y - y - 1); if (fzread(line, bitmap->size_x / 2, 1, f)!=1) goto out_bitmap_mask; /* convert */ for(k=bitmap->size_x-1;k>=0;--k) { if (k & 1) line[k] = line[k/2] & 0xF; else line[k] = line[k/2] >> 4; } } } /* read bitmap mask data (1 bit per pixel) */ for(y=0;y<bitmap->size_y;++y) { unsigned x ; unsigned char* line = adv_bitmap_line(*bitmap_mask, bitmap->size_y - y - 1); x = 0; while (x < bitmap->size_x) { unsigned bc; int b = fzgetc(f); if (b==EOF) goto out_bitmap_mask; if (x + 8 > bitmap->size_x) bc = bitmap->size_x - x; /* waste unused bit */ else bc = 8; x += bc; while (bc) { if (b & 0x80) *line = 0; else *line = 1; b = b << 1; ++line; --bc; } } } free(entry); return bitmap; } goto out_entry; out_bitmap_mask: adv_bitmap_free(*bitmap_mask); out_bitmap: adv_bitmap_free(bitmap); out_entry: free(entry); out: return 0; }