# SVC_UncompressLZ8FromDevice

## Syntax

      #include <nitro/os/common/systemCall.h>

      s32 SVC_UncompressLZ8FromDevice( const void* srcp,
                                  void* destp,
                                  const void* paramp,
                                  const MIReadStreamCallbacks* callbacks );

## Arguments

srcp | Source address where the LZ77 compressed data is stored.
destp | Destination address for decompression.
paramp | Parameter address that is passed to the `initStream` function of the `MIReadStreamCallbacks` structure.
callbacks | Address of the `MIReadStreamCallbacks` socket.

## Return Values

A value of 0 or higher denotes the decompressed size. A value less than 0 denotes an error.

## Description

This function decompresses LZ77 compressed data and writes the data to the specified region of memory.

Decompresses compressed data that is specified by srcp, and stores the result in the area specified in destp.

Compressed data on devices that are not memory-mapped can be decompressed directly without using a temporary buffer. You can also decompress in RAM where byte-level access is not possible.

The data specified by srcp should be data that was compressed using the command "`ntrcomp -l 2`". The boundary restrictions of srcp depend on the implementation of the `initStream` callback.

Sample code

    s32 NVRAMi_UncompressLZ8( const u8 *nvram, void *ram, int limit )
    {
        static const MIReadStreamCallbacks cb = {NVRAMi_InitReadStream, NVRAMi_TerminateReadStream,
                                                 NVRAMi_ReadByteStream, NULL, NVRAMi_ReadWordStream};

        return SVC_UncompressLZ8FromDevice( nvram, ram, &limit, &cb );
    }

    s32 NVRAMi_InitReadStream( const u8 *nvram, void *ram, const void *param )
    {
        int limit = *(int*)param;
        u32 comp_header;
        u32 address = (u32)nvram;
        u8  adr[3];
        int size;
        int i;
        s32 retval;

        adr[0] = (u8)(address >> 16);
        adr[1] = (u8)(address >> 8);
        adr[2] = (u8)(address);

        // Send 4 bytes for the instruction portion
        SPI_Wait();
        NVRAM_SPIChangeMode( SPI_TRANSMODE_CONTINUOUS );
        SPI_Send( NVRAM_INSTRUCTION_READ );
        for (i = 0; i < 3; i++)
        {
            SPI_Wait();
            SPI_Send(adr[i]);
        }

        // preload
        SPI_Wait();
        SPI_Dummy();

        comp_header = NVRAMi_ReadWordStream( nvram );
        retval = comp_header;

        size = comp_header >> 8;
        if ( (int)(nvram + size) > NVRAM_SIZE_MAX ||
             size <= 0 || size > limit )
        {
            retval = -1;
        }

        return retval;
    }

    u8 NVRAMi_ReadByteStream( const u8 *nvram )
    {
        u8 byte;

        SPI_Wait();
        byte = SPI_Receive();

        // preload
        SPI_Dummy();

        return  byte;
    }

    u32 NVRAMi_ReadWordStream( const u8 *nvram )
    {
        u32 word;
        u8* bytep = (u8*)&word;
        int i;

        for (i=0; i<4; i++)
        {
            *bytep++ = NVRAMi_ReadByteStream( NULL );
        }

        return word;
    }

    s32 NVRAMi_TerminateReadStream( const u8 *nvram )
    {
        // 1st dummy read
        SPI_Wait();
        (void)SPI_Receive();

        // 2nd dummy read
        NVRAM_SPIChangeMode(SPI_TRANSMODE_1BYTE);
        SPI_DummyWait();
        (void)SPI_Receive();

        return 0;
    }

## See Also

`SVC_UncompressLZ16FromDevice
`

## Revision History

2007/10/22 Initial version.

CONFIDENTIAL