source: rtems-tools/linkers/rld-compression.cpp @ f10123a

4.104.115
Last change on this file since f10123a was 93e80d5, checked in by Chris Johns <chrisj@…>, on 11/29/12 at 08:04:12

Compress as blocks.

The LZ77 compressor works with blocks. Each block is prefixed with
a header that defines the output size of the block being compressed.

  • Property mode set to 100644
File size: 3.4 KB
Line 
1/*
2 * Copyright (c) 2012, Chris Johns <chrisj@rtems.org>
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16/**
17 * @file
18 *
19 * @ingroup rtems_ld
20 *
21 * @brief RTEMS Linker.
22 *
23 */
24
25#if HAVE_CONFIG_H
26#include "config.h"
27#endif
28
29#include <fstream>
30#include <iostream>
31
32#include <errno.h>
33#include <string.h>
34
35#include <rld.h>
36#include <rld-compression.h>
37
38#include "fastlz.h"
39
40namespace rld
41{
42  namespace compress
43  {
44    compressor::compressor (files::image& image,
45                            size_t        size,
46                            bool          compress)
47      : image (image),
48        size (size),
49        compress (compress),
50        buffer (0),
51        io (0),
52        level (0),
53        total (0),
54        total_compressed (0)
55    {
56      if (size > 0xffff)
57        throw rld::error ("Size too big, 16 bits only", "compression");
58
59      buffer = new uint8_t[size];
60      io = new uint8_t[size + (size / 10)];
61    }
62
63    compressor::~compressor ()
64    {
65      flush ();
66      delete [] buffer;
67      delete [] io;
68    }
69
70    void
71    compressor::write (const void* data_, size_t length)
72    {
73      const uint8_t* data = static_cast <const uint8_t*> (data_);
74
75      while (length)
76      {
77        size_t appending;
78
79        if (length > (size - level))
80          appending = size - level;
81        else
82          appending = length;
83
84        ::memcpy ((void*) (buffer + level), data, appending);
85
86        level += appending;
87        length -= appending;
88
89        output ();
90      }
91    }
92
93    void
94    compressor::write (files::image& input, off_t offset, size_t length)
95    {
96      input.seek (offset);
97
98      while (length)
99      {
100        size_t appending;
101
102        if (length > (size - level))
103          appending = size - level;
104        else
105          appending = length;
106
107        input.read ((void*) (buffer + level), appending);
108
109        level += appending;
110        length -= appending;
111
112        output ();
113      }
114    }
115
116    void
117    compressor::flush ()
118    {
119      output (true);
120    }
121
122    size_t
123    compressor::transferred () const
124    {
125      return total;
126    }
127
128    size_t
129    compressor::compressed () const
130    {
131      return total_compressed;
132    }
133
134    void
135    compressor::output (bool forced)
136    {
137      if ((forced && level) || (level >= size))
138      {
139        total += level;
140
141        if (compress)
142        {
143          int     writing = ::fastlz_compress (buffer, level, io);
144          uint8_t header[2];
145
146          header[0] = writing >> 8;
147          header[1] = writing;
148
149          image.write (header, 2);
150          image.write (io, writing);
151
152          total_compressed += 2 + writing;
153        }
154        else
155        {
156          image.write (buffer, level);
157        }
158
159        level = 0;
160      }
161    }
162
163  }
164}
Note: See TracBrowser for help on using the repository browser.