summaryrefslogtreecommitdiffstats
path: root/src/libs/7zip/win/CPP/7zip/Archive/Common/CoderMixer2.h
blob: 50e7077ae815d5bacfe7329eb99874450c94aed9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
// CoderMixer2.h

#ifndef __CODER_MIXER2_H
#define __CODER_MIXER2_H

#include "../../../Common/MyCom.h"
#include "../../../Common/MyVector.h"

#include "../../ICoder.h"

namespace NCoderMixer {

struct CBindPair
{
  UInt32 InIndex;
  UInt32 OutIndex;
};

struct CCoderStreamsInfo
{
  UInt32 NumInStreams;
  UInt32 NumOutStreams;
};

struct CBindInfo
{
  CRecordVector<CCoderStreamsInfo> Coders;
  CRecordVector<CBindPair> BindPairs;
  CRecordVector<UInt32> InStreams;
  CRecordVector<UInt32> OutStreams;

  void Clear()
  {
    Coders.Clear();
    BindPairs.Clear();
    InStreams.Clear();
    OutStreams.Clear();
  }

  /*
  UInt32 GetCoderStartOutStream(UInt32 coderIndex) const
  {
    UInt32 numOutStreams = 0;
    for (UInt32 i = 0; i < coderIndex; i++)
      numOutStreams += Coders[i].NumOutStreams;
    return numOutStreams;
  }
  */


  void GetNumStreams(UInt32 &numInStreams, UInt32 &numOutStreams) const
  {
    numInStreams = 0;
    numOutStreams = 0;
    FOR_VECTOR (i, Coders)
    {
      const CCoderStreamsInfo &coderStreamsInfo = Coders[i];
      numInStreams += coderStreamsInfo.NumInStreams;
      numOutStreams += coderStreamsInfo.NumOutStreams;
    }
  }

  int FindBinderForInStream(UInt32 inStream) const
  {
    FOR_VECTOR (i, BindPairs)
      if (BindPairs[i].InIndex == inStream)
        return i;
    return -1;
  }
  int FindBinderForOutStream(UInt32 outStream) const
  {
    FOR_VECTOR (i, BindPairs)
      if (BindPairs[i].OutIndex == outStream)
        return i;
    return -1;
  }

  UInt32 GetCoderInStreamIndex(UInt32 coderIndex) const
  {
    UInt32 streamIndex = 0;
    for (UInt32 i = 0; i < coderIndex; i++)
      streamIndex += Coders[i].NumInStreams;
    return streamIndex;
  }

  UInt32 GetCoderOutStreamIndex(UInt32 coderIndex) const
  {
    UInt32 streamIndex = 0;
    for (UInt32 i = 0; i < coderIndex; i++)
      streamIndex += Coders[i].NumOutStreams;
    return streamIndex;
  }


  void FindInStream(UInt32 streamIndex, UInt32 &coderIndex,
      UInt32 &coderStreamIndex) const
  {
    for (coderIndex = 0; coderIndex < (UInt32)Coders.Size(); coderIndex++)
    {
      UInt32 curSize = Coders[coderIndex].NumInStreams;
      if (streamIndex < curSize)
      {
        coderStreamIndex = streamIndex;
        return;
      }
      streamIndex -= curSize;
    }
    throw 1;
  }
  void FindOutStream(UInt32 streamIndex, UInt32 &coderIndex,
      UInt32 &coderStreamIndex) const
  {
    for (coderIndex = 0; coderIndex < (UInt32)Coders.Size(); coderIndex++)
    {
      UInt32 curSize = Coders[coderIndex].NumOutStreams;
      if (streamIndex < curSize)
      {
        coderStreamIndex = streamIndex;
        return;
      }
      streamIndex -= curSize;
    }
    throw 1;
  }
};

class CBindReverseConverter
{
  UInt32 _numSrcOutStreams;
  NCoderMixer::CBindInfo _srcBindInfo;
  CRecordVector<UInt32> _srcInToDestOutMap;
  CRecordVector<UInt32> _srcOutToDestInMap;
  CRecordVector<UInt32> _destInToSrcOutMap;
public:
  UInt32 NumSrcInStreams;
  CRecordVector<UInt32> DestOutToSrcInMap;

  CBindReverseConverter(const NCoderMixer::CBindInfo &srcBindInfo);
  void CreateReverseBindInfo(NCoderMixer::CBindInfo &destBindInfo);
};

void SetSizes(const UInt64 **srcSizes, CRecordVector<UInt64> &sizes,
    CRecordVector<const UInt64 *> &sizePointers, UInt32 numItems);

struct CCoderInfo2
{
  CMyComPtr<ICompressCoder> Coder;
  CMyComPtr<ICompressCoder2> Coder2;
  UInt32 NumInStreams;
  UInt32 NumOutStreams;

  CRecordVector<UInt64> InSizes;
  CRecordVector<UInt64> OutSizes;
  CRecordVector<const UInt64 *> InSizePointers;
  CRecordVector<const UInt64 *> OutSizePointers;

  CCoderInfo2(UInt32 numInStreams, UInt32 numOutStreams):
      NumInStreams(numInStreams),
      NumOutStreams(numOutStreams) {}
  void SetCoderInfo(const UInt64 **inSizes, const UInt64 **outSizes);

  HRESULT QueryInterface(REFGUID iid, void** pp) const
  {
    IUnknown *p = Coder ? (IUnknown *)Coder : (IUnknown *)Coder2;
    return p->QueryInterface(iid, pp);
  }
};

class CCoderMixer2
{
public:
  virtual HRESULT SetBindInfo(const CBindInfo &bindInfo) = 0;
  virtual void ReInit() = 0;
  virtual void SetCoderInfo(UInt32 coderIndex, const UInt64 **inSizes, const UInt64 **outSizes) = 0;
};

}

#endif