static int write_device(AudioDevice *ad, unsigned char *data, int size) { ALSA_data *alsa = (ALSA_data *)ad->private_data; snd_pcm_sframes_t r; ssize_t unit = snd_pcm_samples_to_bytes(alsa->fd, 1) * ad->channels; snd_pcm_uframes_t count = size / unit; while (count > 0) { if ((r = snd_pcm_writei(alsa->fd, data, count)) == -EAGAIN) { //debug_message_fnc(" EAGAIN\n"); snd_pcm_wait(alsa->fd, 1000); } else if (r > 0) { //debug_message_fnc(" wrote %d bytes\n", (int)(r * unit)); ad->bytes_written += r * unit; count -= r; data += r * unit; } else if (r == -EPIPE) { debug_message_fnc("EPIPE: "); if (snd_pcm_state(alsa->fd) == SND_PCM_STATE_XRUN) { if ((r = snd_pcm_prepare(alsa->fd)) < 0) { debug_message("failed\n"); warning_fnc("snd_pcm_prepare() failed."); } else { debug_message("OK\n"); } } } else { warning_fnc(" r = %d < 0...\n", (int)r); } } return 1; }
static int bytes_written(AudioDevice *ad) { ALSA_data *alsa = (ALSA_data *)ad->private_data; snd_pcm_sframes_t delay; snd_pcm_state_t state; if (!alsa) return -1; state = snd_pcm_state(alsa->fd); if (state == SND_PCM_STATE_OPEN || state == SND_PCM_STATE_SETUP) return -1; if (snd_pcm_delay(alsa->fd, &delay) < 0) warning_fnc("snd_pcm_delay() failed.\n"); return ad->bytes_written - snd_pcm_samples_to_bytes(alsa->fd, delay) * ad->channels; }
static int load_image(Image *p, Stream *st) { unsigned char buf[BUFSIZE], *pp, *d; unsigned int file_size, header_size, image_size, offset_to_image; unsigned short int biPlanes; unsigned int bytes_per_pal; int i, c, c2, y, compress_method; if (stream_read(st, buf, 12) != 12) return 0; file_size = utils_get_little_uint32(&buf[0]); offset_to_image = utils_get_little_uint32(&buf[8]); if (file_size < offset_to_image) return 0; if (!stream_read_little_uint32(st, &header_size)) return 0; if (header_size > 64) return 0; if (stream_read(st, buf, header_size - 4) != (int)(header_size - 4)) return 0; if (header_size >= WIN_BMP_HEADER_SIZE) { image_width(p) = utils_get_little_uint32(&buf[0]); image_height(p) = utils_get_little_uint32(&buf[4]); biPlanes = utils_get_little_uint16(&buf[8]); p->bits_per_pixel = utils_get_little_uint16(&buf[10]); } else { image_width(p) = utils_get_little_uint16(&buf[0]); image_height(p) = utils_get_little_uint16(&buf[2]); biPlanes = utils_get_little_uint16(&buf[4]); p->bits_per_pixel = utils_get_little_uint16(&buf[6]); } if (biPlanes != 1) return 0; if (image_width(p) > 10000 || image_height(p) > 10000) return 0; switch (p->bits_per_pixel) { case 1: p->type = _BITMAP_MSBFirst; /* XXX: check order */ p->depth = p->bits_per_pixel; break; case 4: p->type = _INDEX44; p->depth = 4; break; case 8: p->type = _INDEX; p->depth = 8; break; case 16: p->type = _RGB555; p->depth = 16; break; case 24: p->type = _BGR24; p->depth = 24; break; case 32: p->type = _BGRA32; p->depth = 24; break; default: show_message("bmp: read_header: unknown bpp %d detected.\n", p->bits_per_pixel); return 0; } compress_method = 0; if (header_size >= WIN_BMP_HEADER_SIZE) { compress_method = utils_get_little_uint16(&buf[12]); image_size = utils_get_little_uint32(&buf[16]); image_size = image_size; // dummy } /* other header informations are intentionally ignored */ if (p->depth <= 8) { p->ncolors = 1 << p->depth; bytes_per_pal = (header_size >= WIN_BMP_HEADER_SIZE) ? 4 : 3; if (p->ncolors * bytes_per_pal > BUFSIZE) { err_message_fnc("BUFSIZE is too small. It must be greater than %d.\n", p->ncolors * bytes_per_pal); return 0; } if (stream_read(st, buf, p->ncolors * bytes_per_pal) != (int)(p->ncolors * bytes_per_pal)) return 0; for (i = 0; i < (int)p->ncolors; i++) { p->colormap[i][0] = buf[bytes_per_pal * i + 2]; p->colormap[i][1] = buf[bytes_per_pal * i + 1]; p->colormap[i][2] = buf[bytes_per_pal * i + 0]; } } else if (p->depth == 16 && compress_method == 3) { /* Read bitmasks */ if (stream_read(st, buf, 3 * 4) != 3 * 4) return 0; unsigned int rm = utils_get_little_uint32(buf); unsigned int gm = utils_get_little_uint32(buf + 4); unsigned int bm = utils_get_little_uint32(buf + 8); if (rm == 0xf800) p->type = _RGB565; else if (rm == 0x7c00) p->type = _RGB555; else warning_fnc("Mask: R %X G %X B %X is not supported\n", rm, gm, bm); compress_method = 0; } image_bpl(p) = (image_width(p) * p->bits_per_pixel) >> 3; image_bpl(p) += (4 - (image_bpl(p) % 4)) % 4; debug_message_fnc("(%d, %d): bpp %d depth %d compress %d\n", image_width(p), image_height(p), p->bits_per_pixel, p->depth, compress_method); if ((d = memory_alloc(image_image(p), image_bpl(p) * image_height(p))) == NULL) return 0; stream_seek(st, offset_to_image, _SET); pp = d + image_bpl(p) * (image_height(p) - 1); switch (compress_method) { case BI_RGB: for (i = (int)(image_height(p) - 1); i >= 0; i--) { stream_read(st, pp, image_bpl(p)); pp -= image_bpl(p); } break; case BI_RLE4: if (p->depth != 4) show_message("Compressed RI_BLE4 bitmap with depth %d != 4.\n", p->depth); /* RLE compressed data */ /* Not complete. */ y = image_height(p); while ((c = stream_getc(st)) != -1 && y >= 0) { if (c != 0) { /* code mode */ c2 = stream_getc(st); show_message_fnc("len %d data %d\n", c, c2); for (i = 0; i < c; i += 2) { *pp++ = (unsigned char)c2; } } else { if ((c = stream_getc(st)) == 0) { /* line end */ show_message_fnc("line end %d\n", y); pp = d + image_bpl(p) * (y - 1); y--; } else if (c == 1) { /* image end */ break; } else if (c == 2) { /* offset */ c = stream_getc(st); c2 = stream_getc(st); show_message_fnc("offset %d, %d\n", c, c2); pp += (c - c2 * image_width(p)) / 2; } else { /* absolute mode */ show_message_fnc("abs len %d\n", c); for (i = 0; i < c; i += 2) *pp++ = (unsigned char)stream_getc(st); if (c % 2 != 0) /* read dummy */ c = stream_getc(st); } } } break; case BI_RLE8: if (p->depth != 8) show_message("Compressed RI_BLE8 bitmap with depth %d != 8.\n", p->depth); /* RLE compressed data */ y = image_height(p); while ((c = stream_getc(st)) != -1 && y >= 0) { if (c != 0) { /* code mode */ c2 = stream_getc(st); for (i = 0; i < c; i++) { *pp++ = (unsigned char)c2; } } else { if ((c = stream_getc(st)) == 0) { /* line end */ pp = d + image_bpl(p) * (y - 1); y--; } else if (c == 1) { /* image end */ break; } else if (c == 2) { /* offset */ c = stream_getc(st); c2 = stream_getc(st); pp += (c - c2 * image_width(p)); } else { /* absolute mode */ for (i = 0; i < c; i++) *pp++ = (unsigned char)stream_getc(st); if (c % 2 != 0) /* read dummy */ c = stream_getc(st); } } } break; default: show_message("Compressed bitmap (method = %d) not supported.\n", compress_method); return 0; } return 1; }