Exemple #1
0
static HRESULT load_articulation(IDirectMusicInstrumentImpl *This, IStream *stream, ULONG length)
{
    HRESULT ret;
    instrument_articulation *articulation;

    if (!This->articulations)
        This->articulations = HeapAlloc(GetProcessHeap(), 0, sizeof(*This->articulations));
    else
        This->articulations = HeapReAlloc(GetProcessHeap(), 0, This->articulations, sizeof(*This->articulations) * (This->nb_articulations + 1));
    if (!This->articulations)
        return E_OUTOFMEMORY;

    articulation = &This->articulations[This->nb_articulations];

    ret = read_from_stream(stream, &articulation->connections_list, sizeof(CONNECTIONLIST));
    if (FAILED(ret))
        return ret;

    articulation->connections = HeapAlloc(GetProcessHeap(), 0, sizeof(CONNECTION) * articulation->connections_list.cConnections);
    if (!articulation->connections)
        return E_OUTOFMEMORY;

    ret = read_from_stream(stream, articulation->connections, sizeof(CONNECTION) * articulation->connections_list.cConnections);
    if (FAILED(ret))
    {
        HeapFree(GetProcessHeap(), 0, articulation->connections);
        return ret;
    }

    subtract_bytes(length, sizeof(CONNECTIONLIST) + sizeof(CONNECTION) * articulation->connections_list.cConnections);

    This->nb_articulations++;

    return S_OK;
}
int main()
{
    for (const auto& test : tests_map)
    {
        auto data = eps::assets_storage::instance().read<eps::rendering::program_data>(test.first);

        std::ifstream vs_result(std::get<0>(test.second));

        if (!vs_result.is_open())
        {
            std::cerr << "could not read data from file " << std::get<0>(test.second) << std::endl;
            continue;
        }

        std::string vertex_shader = read_from_stream(vs_result);
        vs_result.close();

        std::ifstream fs_result(std::get<1>(test.second));

        if (!fs_result.is_open())
        {
            std::cerr << "could not read data from file " << std::get<1>(test.second) << std::endl;
            continue;
        }

        std::string fragment_shader = read_from_stream(fs_result);
        fs_result.close();

        if (!data)
        {
            if (vertex_shader.empty() && fragment_shader.empty())
            {
                std::cout << test.first << " with unknown version PASS" << std::endl;
            }
            else
            {
                std::cerr << "could not read data from asset " << test.first << std::endl;
            }

            continue;
        }

        if (vertex_shader.empty() && fragment_shader.empty())
        {
            std::cerr << test.first << " with unknown version FAIL" << std::endl;
        }

        if ((vertex_shader == data.value().v_shader()) && fragment_shader == data.value().f_shader())
        {
            std::cout << test.first << " with known version PASS" << std::endl;
        }
        else
        {
            std::cerr << test.first << " with known version FAIL" << std::endl;
        }
    }
}
Exemple #3
0
// read a graph from the given file, return success
bool t_dir_graph::read_from_file(const char* filename){
	
	if(!strcmp(filename,"stdin")) read_from_stream(cin); else {
		ifstream* file = new ifstream(filename, ios::in|ios::binary);
		
		if(!file) {
			cout << "error opening \"" << filename << "\"\n";
			return false;
		}
		dbgcout << "reading data from " << filename << "\n";
		read_from_stream(*file);
		delete file;
	}
	return true;
}
Exemple #4
0
int main(int argc, char **argv)
{
	if (1 == argc) {
		read_from_stream(stdin);
	} else {
		printf("%s\n", USING);
		exit(EXIT_FAILURE);
	}
}
Exemple #5
0
	void load_bitmap()
	{
		std::ifstream stream(file_name_.c_str(), std::ios::binary);
		if (!stream)
		{
			std::cerr << "bitmap_image::load_bitmap() ERROR: bitmap_image - file " << file_name_ << " not found!" << std::endl;
			return;
		}
		bitmap_file_header bfh;
		bitmap_information_header bih;
		read_from_stream(stream, &bfh, sizeof(bfh));
		read_from_stream(stream, &bih, sizeof(bih));
		if (bfh.type != 19778)
		{
			stream.close();
			std::cerr << "bitmap_image::load_bitmap() ERROR: bitmap_image - Invalid type value " << bfh.type << " expected 19778." << std::endl;
			return;
		}
		if (bih.bit_count != 24)
		{
			stream.close();
			std::cerr << "bitmap_image::load_bitmap() ERROR: bitmap_image - Invalid bit depth " << bih.bit_count << " expected 24." << std::endl;
			return;
		}
		height_ = bih.height;
		width_ = bih.width;
		bytes_per_pixel_ = bih.bit_count >> 3;
		unsigned int padding = (4 - ((3 * width_) % 4)) % 4;
		char padding_data[4] = { 0,0,0,0 };
		create_bitmap();
		for (unsigned int i = 0; i < height_; ++i)
		{
			unsigned char* data_ptr = row(height_ - i - 1);
			stream.read(reinterpret_cast<char*>(data_ptr), sizeof(char) * bytes_per_pixel_ * width_);
			stream.read(padding_data, padding);
		}
	}
/**
 * Main SSL demonstration code entry point
 */
int main(int argc, char** argv) {
 //   char* host_and_port = argv[1]; /* localhost:4422 */
//    char* server_request = argv[2]; /* "GET / \r\n\r\n" */
//    char* store_path = argv[3]; /* /home/user/projects/sslclient/certificate.pem */
//    char store_type = argv[4][0]; /* f = file, anything else is a directory structure */
//    char connection_type = argv[5][0]; /* e = encrypted, anything else is unencrypted */
 
    char buffer[4096];
    buffer[0] = 0;
 
    BIO* bio;
    SSL_CTX* ctx = NULL;
    SSL* ssl = NULL;
 
    /* initilise the OpenSSL library */
    init_openssl();
 
    /* encrypted link */
/*
    if (connection_type == 'e') {
 
        if ((bio = connect_encrypted(host_and_port, store_path, store_type, &ctx, &ssl)) == NULL)
            return (EXIT_FAILURE);
    }*/
        /* unencrypted link */
    //else if ((bio = connect_unencrypted(host_and_port)) == NULL)
        //return (EXIT_FAILURE);

	if ((bio = connect_encrypted("127.0.0.1:7543" , &ctx , &ssl)) == NULL)
        return (EXIT_FAILURE);
	
	char* server_request = "GET / \r\n\r\n";
    write_to_stream(bio, server_request, strlen(server_request));
    read_from_stream(bio, buffer, 4096);
    printf("%s\r\n", buffer);
 
    if (close_connection(bio) == 0)
        return (EXIT_FAILURE);
 
    /* clean up the SSL context resources for the encrypted link */
    //if (connection_type == 'e')
        SSL_CTX_free(ctx);
 
    return (EXIT_SUCCESS);
}
void deal_with_stream(bionet_stream_t *stream) {
    switch (bionet_stream_get_direction(stream)) {
        case BIONET_STREAM_DIRECTION_PRODUCER: {
            read_from_stream(stream);
            fprintf(stderr, "read_from_stream() returned!\n");
            exit(1);
        }

        case BIONET_STREAM_DIRECTION_CONSUMER: {
            write_to_stream(stream);
            fprintf(stderr, "write_to_stream() returned!\n");
            exit(1);
        }

        default: {
            fprintf(stderr, "stream %s has unknown direction!\n", bionet_stream_get_name(stream));
            exit(1);
        }
    }
}
Exemple #8
0
static void
prepare (GeglOperation *operation)
{
  GeglProperties *o = GEGL_PROPERTIES (operation);
  Priv *p = (o->user_data) ? o->user_data : g_new0 (Priv, 1);
  GError *error = NULL;
  GFile *file = NULL;
  guchar *buffer;
  gsize read;

  g_assert (p != NULL);

  if (p->file != NULL && (o->uri || o->path))
    {
      if (o->uri && strlen (o->uri) > 0)
        file = g_file_new_for_uri (o->uri);
      else if (o->path && strlen (o->path) > 0)
        file = g_file_new_for_path (o->path);
      if (file != NULL)
        {
          if (!g_file_equal (p->file, file))
            cleanup (operation);
          g_object_unref (file);
        }
    }

  o->user_data = (void*) p;

  if (p->config == NULL)
    {
      p->stream = gegl_gio_open_input_stream (o->uri, o->path, &p->file, &error);
      if (p->stream == NULL)
        {
          g_warning (error->message);
          g_error_free (error);
          cleanup (operation);
          return;
        }

      p->config = g_try_new (WebPDecoderConfig, 1);
      p->decoder = WebPINewDecoder (&p->config->output);

      g_assert (p->config != NULL);

      if (!WebPInitDecoderConfig (p->config))
        {
          g_warning ("could not initialise WebP decoder configuration");
          cleanup (operation);
          return;
        }

      read = read_from_stream (p->stream, &buffer, IO_BUFFER_SIZE);
      if (WebPGetFeatures (buffer, read, &p->config->input) != VP8_STATUS_OK)
        {
          g_warning ("failed reading WebP image file");
          cleanup (operation);
          g_free (buffer);
          return;
        }

      if (!query_webp (operation))
        {
          g_warning ("could not query WebP image file");
          cleanup (operation);
          g_free (buffer);
          return;
        }

       WebPIAppend (p->decoder, buffer, read);

      g_free (buffer);
    }

  gegl_operation_set_format (operation, "output", p->format);
}
Exemple #9
0
// The main entry point of the program.
// This is where the magic happens.
// --------------------------------------------------------
int main(int argc, char** argv)
{
    // Parse the command-line options.
    if (!parse_options(argc, argv))
    {
        help(argv[0]);
        return EXIT_FAILURE;
    }

    // Read from standard input.
    wchar_t* input = read_from_stream(stdin);
    if (input == NULL) goto out_of_memory;
    size_t len = wcslen(input);

    // Chomp a trailing newline.
    if (len > 0 && input[len-1] == L'\n')
    {
        input[len-1] = L'\0';
        len--;
    }

    // Allocate space for the output string.
    wchar_t* output = malloc(sizeof(wchar_t)*(options.length+1));
    if (output == NULL)
    {
        free(input);
        goto out_of_memory;
    }

    // If the input is shorter than the ticker width, just
    // return the input.
    if (!options.always_scroll && len <= options.length)
    {
        memcpy(output, input, sizeof(wchar_t)*len);
        fill_with_blanks(output, len, options.length);
    }

    // Otherwise, clip the output and offset it by the
    // modulus of the current UNIX timestamp.
    else
    {
        ssize_t end = (current_time_ms()/options.tick) % (len+options.length);
        if (options.reverse) end = (len+options.length)-end;
        ssize_t start = end - options.length;
        if (start < 0)
        {
            fill_with_blanks(output, 0, -start);
            memcpy(output-start, input, end*sizeof(wchar_t));
            if (options.always_scroll && end > len)
                fill_with_blanks(output, options.length-(end-len),
                                         options.length);
        }
        else
        {
            if (end > len)
            {
                ssize_t overflow = end - len;
                fill_with_blanks(output, options.length-overflow,
                                         options.length);
                end = len;
            }
            memcpy(output, input+start, (end-start)*sizeof(wchar_t));
        }
    }
    free(input);

    // Convert the output buffer back to the native
    // encoding and output it.
    output[options.length] = L'\0';
    wprintf(output);
    free(output);

    return EXIT_SUCCESS;

out_of_memory:
    fputs("ERROR\n", stdout);
    fputs("Out of memory.\n", stderr);
    return EXIT_FAILURE;
}
Exemple #10
0
/* aux. function that completely loads instrument; my tests indicate that it's 
   called somewhere around IDirectMusicCollection_GetInstrument */
HRESULT WINAPI IDirectMusicInstrumentImpl_Custom_Load (LPDIRECTMUSICINSTRUMENT iface, LPSTREAM stream)
{
    ICOM_THIS_MULTI(IDirectMusicInstrumentImpl, InstrumentVtbl, iface);
    LARGE_INTEGER move;
    FOURCC fourcc;
    DWORD bytes;
    HRESULT hr;

    TRACE("(%p, %p, offset = %s)\n", This, stream, wine_dbgstr_longlong(This->liInstrumentPosition.QuadPart));

    hr = IStream_Seek(stream, This->liInstrumentPosition, STREAM_SEEK_SET, NULL);
    if(FAILED(hr)){
        WARN("IStream_Seek failed: %08x\n", hr);
        goto load_failure;
    }

    hr = read_from_stream(stream, &fourcc, sizeof(fourcc));
    if(FAILED(hr))
        goto load_failure;

    if(fourcc != FOURCC_LIST){
        WARN("Loading failed: Expected LIST chunk, got: %s\n", debugstr_fourcc(fourcc));
        goto load_failure;
    }

    hr = read_from_stream(stream, &bytes, sizeof(bytes));
    if(FAILED(hr))
        goto load_failure;

    TRACE("LIST chunk: %u bytes\n", bytes);
    while(1){
        hr = read_from_stream(stream, &fourcc, sizeof(fourcc));
        if(FAILED(hr))
            goto load_failure;

        switch(fourcc){
        case FOURCC_INS:
            TRACE("INS  chunk: (no byte count)\n");
            hr = load_instrument(This, stream, bytes - sizeof(FOURCC));
            if(FAILED(hr))
                goto load_failure;
            break;

        default:
            hr = read_from_stream(stream, &bytes, sizeof(bytes));
            if(FAILED(hr))
                goto load_failure;

            TRACE("Unknown chunk %s: %u bytes\n", debugstr_fourcc(fourcc), bytes);

            move.QuadPart = bytes;
            hr = IStream_Seek(stream, move, STREAM_SEEK_CUR, NULL);
            if(FAILED(hr)){
                WARN("IStream_Seek failed: %08x\n", hr);
                return hr;
            }

            break;
        }
    }

    return S_OK;

load_failure:
    return DMUS_E_UNSUPPORTED_STREAM;
}
Exemple #11
0
static HRESULT load_instrument(IDirectMusicInstrumentImpl *This, IStream *stream, DWORD length)
{
    HRESULT hr;
    FOURCC fourcc;
    DWORD bytes;
    LARGE_INTEGER move;

    while(length){
        hr = read_from_stream(stream, &fourcc, sizeof(fourcc));
        if(FAILED(hr))
            return hr;

        hr = read_from_stream(stream, &bytes, sizeof(bytes));
        if(FAILED(hr))
            return hr;

        length = subtract_bytes(length, sizeof(fourcc) + sizeof(bytes));

        switch(fourcc){
        case FOURCC_INSH:
            TRACE("INSH chunk: %u bytes\n", bytes);
            hr = read_from_stream(stream, This->pHeader, sizeof(*This->pHeader));
            if(FAILED(hr))
                return hr;

            move.QuadPart = bytes - sizeof(*This->pHeader);
            hr = IStream_Seek(stream, move, STREAM_SEEK_CUR, NULL);
            if(FAILED(hr)){
                WARN("IStream_Seek failed: %08x\n", hr);
                return hr;
            }

            length = subtract_bytes(length, bytes);
            break;

        case FOURCC_DLID:
            TRACE("DLID chunk: %u bytes\n", bytes);
            hr = read_from_stream(stream, This->pInstrumentID, sizeof(*This->pInstrumentID));
            if(FAILED(hr))
                return hr;

            move.QuadPart = bytes - sizeof(*This->pInstrumentID);
            hr = IStream_Seek(stream, move, STREAM_SEEK_CUR, NULL);
            if(FAILED(hr)){
                WARN("IStream_Seek failed: %08x\n", hr);
                return hr;
            }

            length = subtract_bytes(length, bytes);
            break;

        default:
            TRACE("Unknown chunk %s: %u bytes\n", debugstr_fourcc(fourcc), bytes);

            move.QuadPart = bytes;
            hr = IStream_Seek(stream, move, STREAM_SEEK_CUR, NULL);
            if(FAILED(hr)){
                WARN("IStream_Seek failed: %08x\n", hr);
                return hr;
            }

            length = subtract_bytes(length, bytes);
            break;
        }
    }

    return S_OK;
}
Exemple #12
0
/**
 * Wrap/Unwrap PKCs#7 containers
 */
static int pkcs7()
{
	char *arg, *file = NULL;
	private_key_t *key = NULL;
	certificate_t *cert = NULL;
	chunk_t data = chunk_empty;
	mem_cred_t *creds;
	int res = 1;
	FILE *in;
	enum {
		OP_NONE,
		OP_SIGN,
		OP_VERIFY,
		OP_ENCRYPT,
		OP_DECRYPT,
		OP_SHOW,
	} op = OP_NONE;

	creds = mem_cred_create();

	while (TRUE)
	{
		switch (command_getopt(&arg))
		{
			case 'h':
				creds->destroy(creds);
				return command_usage(NULL);
			case 'i':
				file = arg;
				continue;
			case 's':
				if (op != OP_NONE)
				{
					goto invalid;
				}
				op = OP_SIGN;
				continue;
			case 'u':
				if (op != OP_NONE)
				{
					goto invalid;
				}
				op = OP_VERIFY;
				continue;
			case 'e':
				if (op != OP_NONE)
				{
					goto invalid;
				}
				op = OP_ENCRYPT;
				continue;
			case 'd':
				if (op != OP_NONE)
				{
					goto invalid;
				}
				op = OP_DECRYPT;
				continue;
			case 'p':
				if (op != OP_NONE)
				{
					goto invalid;
				}
				op = OP_SHOW;
				continue;
			case 'k':
				key = lib->creds->create(lib->creds,
										 CRED_PRIVATE_KEY, KEY_RSA,
										 BUILD_FROM_FILE, arg, BUILD_END);
				if (!key)
				{
					fprintf(stderr, "parsing private key failed\n");
					goto end;
				}
				creds->add_key(creds, key);
				continue;
			case 'c':
				cert = lib->creds->create(lib->creds,
										  CRED_CERTIFICATE, CERT_X509,
										  BUILD_FROM_FILE, arg, BUILD_END);
				if (!cert)
				{
					fprintf(stderr, "parsing certificate failed\n");
					goto end;
				}
				creds->add_cert(creds, TRUE, cert);
				continue;
			case EOF:
				break;
			default:
			invalid:
				creds->destroy(creds);
				return command_usage("invalid --pkcs7 option");
		}
		break;
	}

	if (file)
	{
		in = fopen(file, "r");
		if (in)
		{
			data = read_from_stream(in);
			fclose(in);
		}
	}
	else
	{
		data = read_from_stream(stdin);
	}

	if (!data.len)
	{
		fprintf(stderr, "reading input failed!\n");
		goto end;
	}
	if (op != OP_SHOW && !cert)
	{
		fprintf(stderr, "requiring a certificate!\n");
		goto end;
	}

	lib->credmgr->add_local_set(lib->credmgr, &creds->set, FALSE);

	switch (op)
	{
		case OP_SIGN:
			if (!key)
			{
				fprintf(stderr, "signing requires a private key\n");
				res = 1;
				break;
			}
			res = sign(data, cert, key);
			break;
		case OP_VERIFY:
			res = verify(data);
			break;
		case OP_ENCRYPT:
			res = encrypt(data, cert);
			break;
		case OP_DECRYPT:
			if (!key)
			{
				fprintf(stderr, "decryption requires a private key\n");
				res = 1;
				break;
			}
			res = decrypt(data);
			break;
		case OP_SHOW:
			res = show(data);
			break;
		default:
			res = 1;
			break;
	}
	lib->credmgr->remove_local_set(lib->credmgr, &creds->set);

end:
	creds->destroy(creds);
	free(data.ptr);
	return res;
}
Exemple #13
0
/* Function that loads all instrument data and which is called from IDirectMusicCollection_GetInstrument as in native */
HRESULT IDirectMusicInstrumentImpl_CustomLoad(IDirectMusicInstrument *iface, IStream *stream)
{
    IDirectMusicInstrumentImpl *This = impl_from_IDirectMusicInstrument(iface);
    HRESULT hr;
    DMUS_PRIVATE_CHUNK chunk;
    ULONG i = 0;
    ULONG length = This->length;

    TRACE("(%p, %p): offset = 0x%s, length = %u)\n", This, stream, wine_dbgstr_longlong(This->liInstrumentPosition.QuadPart), This->length);

    if (This->loaded)
        return S_OK;

    hr = IStream_Seek(stream, This->liInstrumentPosition, STREAM_SEEK_SET, NULL);
    if (FAILED(hr))
    {
        WARN("IStream_Seek failed: %08x\n", hr);
        return DMUS_E_UNSUPPORTED_STREAM;
    }

    This->regions = HeapAlloc(GetProcessHeap(), 0, sizeof(*This->regions) * This->header.cRegions);
    if (!This->regions)
        return E_OUTOFMEMORY;

    while (length)
    {
        hr = read_from_stream(stream, &chunk, sizeof(chunk));
        if (FAILED(hr))
            goto error;

        length = subtract_bytes(length, sizeof(chunk) + chunk.dwSize);

        switch (chunk.fccID)
        {
            case FOURCC_INSH:
            case FOURCC_DLID:
                TRACE("Chunk %s: %u bytes\n", debugstr_fourcc(chunk.fccID), chunk.dwSize);

                /* Instrument header and id are already set so just skip */
                hr = advance_stream(stream, chunk.dwSize);
                if (FAILED(hr))
                    goto error;

                break;

            case FOURCC_LIST: {
                DWORD size = chunk.dwSize;

                TRACE("LIST chunk: %u bytes\n", chunk.dwSize);

                hr = read_from_stream(stream, &chunk.fccID, sizeof(chunk.fccID));
                if (FAILED(hr))
                    goto error;

                size = subtract_bytes(size, sizeof(chunk.fccID));

                switch (chunk.fccID)
                {
                    case FOURCC_LRGN:
                        TRACE("LRGN chunk (regions list): %u bytes\n", size);

                        while (size)
                        {
                            hr = read_from_stream(stream, &chunk, sizeof(chunk));
                            if (FAILED(hr))
                                goto error;

                            if (chunk.fccID != FOURCC_LIST)
                            {
                                TRACE("Unknown chunk %s: %u bytes\n", debugstr_fourcc(chunk.fccID), chunk.dwSize);
                                goto error;
                            }

                            hr = read_from_stream(stream, &chunk.fccID, sizeof(chunk.fccID));
                            if (FAILED(hr))
                                goto error;

                            if (chunk.fccID == FOURCC_RGN)
                            {
                                TRACE("RGN chunk (region): %u bytes\n", chunk.dwSize);
                                hr = load_region(This, stream, &This->regions[i++], chunk.dwSize - sizeof(chunk.fccID));
                            }
                            else
                            {
                                TRACE("Unknown chunk %s: %u bytes\n", debugstr_fourcc(chunk.fccID), chunk.dwSize);
                                hr = advance_stream(stream, chunk.dwSize - sizeof(chunk.fccID));
                            }
                            if (FAILED(hr))
                                goto error;

                            size = subtract_bytes(size, chunk.dwSize + sizeof(chunk));
                        }
                        break;

                    case FOURCC_LART:
                        TRACE("LART chunk (articulations list): %u bytes\n", size);

                        while (size)
                        {
                            hr = read_from_stream(stream, &chunk, sizeof(chunk));
                            if (FAILED(hr))
                                goto error;

                            if (chunk.fccID == FOURCC_ART1)
                            {
                                TRACE("ART1 chunk (level 1 articulation): %u bytes\n", chunk.dwSize);
                                hr = load_articulation(This, stream, chunk.dwSize);
                            }
                            else
                            {
                                TRACE("Unknown chunk %s: %u bytes\n", debugstr_fourcc(chunk.fccID), chunk.dwSize);
                                hr = advance_stream(stream, chunk.dwSize);
                            }
                            if (FAILED(hr))
                                goto error;

                            size = subtract_bytes(size, chunk.dwSize + sizeof(chunk));
                        }
                        break;

                    default:
                        TRACE("Unknown chunk %s: %u bytes\n", debugstr_fourcc(chunk.fccID), chunk.dwSize);

                        hr = advance_stream(stream, chunk.dwSize - sizeof(chunk.fccID));
                        if (FAILED(hr))
                            goto error;

                        size = subtract_bytes(size, chunk.dwSize - sizeof(chunk.fccID));
                        break;
                }
                break;
            }

            default:
                TRACE("Unknown chunk %s: %u bytes\n", debugstr_fourcc(chunk.fccID), chunk.dwSize);

                hr = advance_stream(stream, chunk.dwSize);
                if (FAILED(hr))
                    goto error;

                break;
        }
    }

    This->loaded = TRUE;

    return S_OK;

error:
    HeapFree(GetProcessHeap(), 0, This->regions);
    This->regions = NULL;

    return DMUS_E_UNSUPPORTED_STREAM;
}
Exemple #14
0
static HRESULT load_region(IDirectMusicInstrumentImpl *This, IStream *stream, instrument_region *region, ULONG length)
{
    HRESULT ret;
    DMUS_PRIVATE_CHUNK chunk;

    TRACE("(%p, %p, %p, %u)\n", This, stream, region, length);

    while (length)
    {
        ret = read_from_stream(stream, &chunk, sizeof(chunk));
        if (FAILED(ret))
            return ret;

        length = subtract_bytes(length, sizeof(chunk));

        switch (chunk.fccID)
        {
            case FOURCC_RGNH:
                TRACE("RGNH chunk (region header): %u bytes\n", chunk.dwSize);

                ret = read_from_stream(stream, &region->header, sizeof(region->header));
                if (FAILED(ret))
                    return ret;

                length = subtract_bytes(length, sizeof(region->header));
                break;

            case FOURCC_WSMP:
                TRACE("WSMP chunk (wave sample): %u bytes\n", chunk.dwSize);

                ret = read_from_stream(stream, &region->wave_sample, sizeof(region->wave_sample));
                if (FAILED(ret))
                    return ret;
                length = subtract_bytes(length, sizeof(region->wave_sample));

                if (!(region->loop_present = (chunk.dwSize != sizeof(region->wave_sample))))
                    break;

                ret = read_from_stream(stream, &region->wave_loop, sizeof(region->wave_loop));
                if (FAILED(ret))
                    return ret;

                length = subtract_bytes(length, sizeof(region->wave_loop));
                break;

            case FOURCC_WLNK:
                TRACE("WLNK chunk (wave link): %u bytes\n", chunk.dwSize);

                ret = read_from_stream(stream, &region->wave_link, sizeof(region->wave_link));
                if (FAILED(ret))
                    return ret;

                length = subtract_bytes(length, sizeof(region->wave_link));
                break;

            default:
                TRACE("Unknown chunk %s (skipping): %u bytes\n", debugstr_fourcc(chunk.fccID), chunk.dwSize);

                ret = advance_stream(stream, chunk.dwSize);
                if (FAILED(ret))
                    return ret;

                length = subtract_bytes(length, chunk.dwSize);
                break;
        }
    }

    return S_OK;
}