Bonjour,
je fais appel à votre aide après une recherche infructueuse sur ce que je souhaite obtenir avec mon code.
Je ne suis pas un développeur, je ne maîtrise pas les subtilités de la programmation en C et en python en autodidacte.
Je souhaite travailler avec un code python qui fait appel un fichier ZeLib.so (je travaille sous ubuntu 20.04).
Ce fichier ZeLib.so provient de la compilation d'un code en C.
Ce code en C permet d’accéder à un gros fichier (>1 Go) et d'en extraire une partie (une tuile). Pour le moment, le code permet d'écrire la tuile sur le disque.
Ce que j'aimerais c'est ne pas passer par l'écriture sur le disque, mais envoyer la tuile extraite vers python, et l'idéal serait sous la forme d'un tableau array.
La tuile qui est sauvegardée, est une image 512x512 couleur.
Comme je suis incompétent en C, je ne sais même pas si techniquement c’est envisageable.
J'ai repéré, du moins il me semble, que les éléments de l'image sont dans la variable buffer (lignes 287 et 293) et proviennent de la fonction findtile,
mais je ne sais pas si je peux envoyer les données vers python et les obtenir en un tableau array gérable par la bibliothèque numpy.

Voici le code source C
Code C : Sélectionner tout - Visualiser dans une fenêtre à part
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
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
// Original code Written by Mathieu Malaterre
// Same license as OpenSlide
/*
 * Very simply VSI + ETS parser. It dumps basic
 * format info and then extract tile from level=0.
 * compile cc -fPIC -shared -o ZeLib.so ZeLib.c
 */
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdint.h>
#include <assert.h>
 
struct sis_header
{
/* 4 */char magic[4]; // SIS0
/* 4 */uint32_t nbytes;
/* 4 */uint32_t version;
/* 4 */uint32_t dim;
/* 8 */uint64_t etsoffset;
/* 4 */uint32_t etsnbytes;
/* 4 */uint32_t dummy0;
/* 8 */uint64_t offsettiles;
/* 4 */uint32_t ntiles;
/* 4 */uint32_t dummy1;
/* 4 */uint32_t dummy2;
/* 4 */uint32_t dummy3;
/* 4 */uint32_t dummy4;
/* 4 */uint32_t dummy5;
};
 
static void sis_header_read( struct sis_header * self, FILE * stream )
{
  static const char SIS_MAGIC[4] = "SIS";
  fread( self->magic, 1, sizeof(self->magic), stream );
  assert( strncmp( self->magic, SIS_MAGIC, 4 ) == 0 );
  fread( (char*)&self->nbytes, 1, sizeof(self->nbytes), stream );
  assert( self->nbytes == 64 ); // size of struct
  fread( (char*)&self->version, 1, sizeof(self->version), stream );
  assert( self->version == 2 ); // version ??
  fread( (char*)&self->dim, 1, sizeof(self->dim), stream );
  assert( self->dim == 4 || self->dim == 5 || self->dim == 6 ); // dim ?
  fread( (char*)&self->etsoffset, 1, sizeof(self->etsoffset), stream );
  assert( self->etsoffset == 64 ); // offset of ETS struct
  fread( (char*)&self->etsnbytes, 1, sizeof(self->etsnbytes), stream );
  assert( self->etsnbytes == 228 ); // size of ETS struct
  fread( (char*)&self->dummy0, 1, sizeof(self->dummy0), stream );
  assert( self->dummy0 == 0 ); // ??
  fread( (char*)&self->offsettiles, 1, sizeof(self->offsettiles), stream ); // offset to tiles
  fread( (char*)&self->ntiles, 1, sizeof(self->ntiles), stream ); // number of tiles
  fread( (char*)&self->dummy1, 1, sizeof(self->dummy1), stream ); // ??
  assert( self->dummy1 == 0 ); // always zero ?
  fread( (char*)&self->dummy2, 1, sizeof(self->dummy2), stream ); // some kind of offset ?
  //assert( dummy2 == 0 ); // not always
  fread( (char*)&self->dummy3, 1, sizeof(self->dummy3), stream );
  assert( self->dummy3 == 0 ); // always zero ?
  fread( (char*)&self->dummy4, 1, sizeof(self->dummy4), stream );
  //assert( dummy4 == 0 ); // not always
  fread( (char*)&self->dummy5, 1, sizeof(self->dummy5), stream );
  assert( self->dummy5 == 0 ); // always zero ?
}
 
static void sis_header_print( struct sis_header * self, FILE * stream )
{
  fprintf( stream, "magic : %s\n"  , self->magic );
  fprintf( stream, "nbytes: %d\n"  , self->nbytes );
  fprintf( stream, "versi : %d\n"  , self->version );
  fprintf( stream, "dim   : %d\n"  , self->dim );
  fprintf( stream, "etsoff: %ld\n" , self->etsoffset );
  fprintf( stream, "etsnby: %d\n"  , self->etsnbytes );
  fprintf( stream, "dummy0: %d\n"  , self->dummy0 );
  fprintf( stream, "offtil: %ld\n" , self->offsettiles );
  fprintf( stream, "ntiles: %d\n"  , self->ntiles );
  fprintf( stream, "dummy1: %d\n"  , self->dummy1 );
  fprintf( stream, "dummy2: %d\n"  , self->dummy2 );
  fprintf( stream, "dummy3: %d\n"  , self->dummy3 );
  fprintf( stream, "dummy4: %d\n"  , self->dummy4 );
  fprintf( stream, "dummy5: %d\n"  , self->dummy5 );
}
 
struct ets_header
{
/* 4 */char magic[4]; // ETS0
/* 4 */uint32_t version;
/* 4 */uint32_t dummy1;
/* 4 */uint32_t dummy2;
/* 4 */uint32_t dummy3;
/* 4 */uint32_t compression;
/* 4 */uint32_t quality;
/* 4 */uint32_t dimx;
/* 4 */uint32_t dimy;
/* 4 */uint32_t dimz;
};
 
static void ets_header_read( struct ets_header * self, FILE * stream )
{
  static const char ETS_MAGIC[4] = "ETS";
  fread( self->magic, 1, sizeof(self->magic), stream );
  assert( strncmp( self->magic, ETS_MAGIC, 4 ) == 0 );
  fread( (char*)&self->version, 1, sizeof(self->version), stream );
  assert( self->version == 0x30001 || self->version == 0x30003 ); // some kind of version ?
  fread( (char*)&self->dummy1, 1, sizeof(self->dummy1), stream );
  assert( self->dummy1 == 2 || self->dummy1 == 4 /* when sis_header->dim == 4 */ );
  fread( (char*)&self->dummy2, 1, sizeof(self->dummy2), stream );
  assert( self->dummy2 == 3 || self->dummy2 == 1 );
  fread( (char*)&self->dummy3, 1, sizeof(self->dummy3), stream );
  assert( self->dummy3 == 4 || self->dummy3 == 1 );
  fread( (char*)&self->compression, 1, sizeof(self->compression), stream ); // codec
  // 0 -> ?
  // 2 -> JPEG ?
  // 3 -> JPEG 2000 ?
  assert( self->compression == 2 || self->compression == 3 || self->compression == 0 );
  fread( (char*)&self->quality, 1, sizeof(self->quality), stream );
  assert( self->quality == 90 || self->quality == 96 || self->quality == 100 ); // some kind of JPEG quality ?
  fread( (char*)&self->dimx, 1, sizeof(self->dimx), stream );
  //assert( self->dimx == 512 ); // always tile of 512x512 ?
  fread( (char*)&self->dimy, 1, sizeof(self->dimy), stream );
  //assert( self->dimy == 512 ); //
  fread( (char*)&self->dimz, 1, sizeof(self->dimz), stream );
  assert( self->dimz == 1 ); // dimz ?
}
static const char *ets_header_getcomp( struct ets_header * self)
{
  if( self->compression == 0 ) return "raw";
  else if( self->compression == 2 ) return "jpg";
  else if( self->compression == 3 ) return "jp2";
  assert( 0 );
  return NULL;
}
static void ets_header_print( struct ets_header * self, FILE * stream )
{
  fprintf( stream, "magic : %s\n", self->magic );
  fprintf( stream, "versio: %d\n", self->version );
  fprintf( stream, "dummy1: %d\n", self->dummy1 );
  fprintf( stream, "dummy2: %d\n", self->dummy2 );
  fprintf( stream, "dummy3: %d\n", self->dummy3 );
  fprintf( stream, "compre: %s\n", ets_header_getcomp(self) );
  fprintf( stream, "qualit: %d\n", self->quality );
  fprintf( stream, "dimx  : %d\n", self->dimx );
  fprintf( stream, "dimy  : %d\n", self->dimy );
  fprintf( stream, "dimz  : %d\n", self->dimz );
}
 
struct tile
{
/* 4 */uint32_t dummy1;
/* 4 */uint32_t coord[3];
/* 4 */uint32_t level;
/* 8 */uint64_t offset;
/* 4 */uint32_t numbytes;
/* 4 */uint32_t dummy2;
};
 
static void tile_read( struct tile * self, FILE * stream )
{
  fread( (char*)&self->dummy1, 1, sizeof(self->dummy1), stream );
  //assert( self->dummy1 == 4 ); // wotsit ?
  fread( (char*)self->coord, 1, sizeof(self->coord), stream );
  fread( (char*)&self->level, 1, sizeof(self->level), stream );
  fread( (char*)&self->offset, 1, sizeof(self->offset), stream );
  fread( (char*)&self->numbytes, 1, sizeof(self->numbytes), stream );
  fread( (char*)&self->dummy2, 1, sizeof(self->dummy2), stream );
  /*
  assert( dummy2 == 0x18c78d || dummy2 == 0x6171e8
  || dummy2 == 0x610138 || dummy2 == 0x21394dc8
  || dummy2 == 0x0 || dummy2 == 0x21893008
  || dummy2 == 0x215bcd88 || dummy2 == 0x2142ef78 || dummy2 == 0x617208 );
   */
}
 
static void tile_print( const struct tile * self, FILE * stream )
{
  fprintf( stream, "coord: %d,%d,%d\n", self->coord[0], self->coord[1], self->coord[2] );
  fprintf( stream, "level:    %d\n"   , self->level );
  fprintf( stream, "offset:   %ld\n"  , self->offset );
  fprintf( stream, "numbytes: %d\n"   , self->numbytes );
  fprintf( stream, "dummy2:   %d\n"   , self->dummy2 );
}
 
static const struct tile *findtile( struct tile *tiles, size_t ntiles, const long coord[3] )
{
  const struct tile *ret = NULL;
  size_t n;
  for( n = 0; n < ntiles; ++n )
    {
    const struct tile * t = tiles + n;
    if( t->level == 0 )
      {
      if( t->coord[0] == coord[0] && t->coord[1] == coord[1] )
        {
        ret = t;
        }
      }
    }
  return ret;
}
 
#define std_max( x, y ) x > y ? x : y
 
int main(char * filename, long startx, long starty)
{
 
  FILE * stream = fopen( filename, "rb" );
 
  /*
  if( argc < 2 ) return 1;
  const char * filename = argv[1];
  FILE * stream = fopen( filename, "rb" );
 */
  // SIS:
  struct sis_header sh;
  //assert( sizeof( sis_header ) == 64 );
  sis_header_read( &sh, stream );
  sis_header_print( &sh, stdout );
 
  // ETS:
  struct ets_header eh;
  ets_header_read( &eh, stream );
  ets_header_print( &eh, stdout );
 
  // individual tiles
  fseek( stream, sh.offsettiles, SEEK_SET );
  struct tile * tiles;
  tiles = (struct tile*)malloc( sh.ntiles * sizeof( struct tile ) );
  uint32_t n;
  for( n = 0; n < sh.ntiles; ++n )
    {
    struct tile t;
    tile_read( &t, stream );
    //tile_print( &t, stdout );
    tiles[n] = t;
    }
 
  // computes tiles dims
  uint32_t tilexmax = 0;
  uint32_t tileymax = 0;
 
  for( n = 0; n < sh.ntiles; ++n )
    {
    const struct tile *t = tiles+n;
    if( t->level == 0 )
      {
      tilexmax = std_max( t->coord[0], tilexmax );
      tileymax = std_max( t->coord[1], tileymax );
      }
    }
  //assert( tilexmax + 1 == 34 );
  //assert( tileymax + 1 == 14 );
 
  // compute image info:
  size_t ImageWidth = eh.dimx*(tilexmax + 1);
  size_t ImageLength = eh.dimy*(tileymax + 1);
  assert( eh.dimz == 1 );
  size_t TileWidth = eh.dimx;
  size_t TileLength = eh.dimy;
 
  size_t TilesAcross = (ImageWidth + TileWidth - 1) / TileWidth;
  size_t TilesDown = (ImageLength + TileLength - 1) / TileLength;
  size_t TilesPerImage = TilesAcross * TilesDown;
 
  fprintf( stdout , "TilesAcross:   %ld\n", TilesAcross );
  fprintf( stdout , "TilesDown:     %ld\n", TilesDown );
  fprintf( stdout , "TilesPerImage: %ld\n", TilesPerImage );
  //size_t linestripe = TilesAcross * TileWidth * 3;
 
  // extract images from level=0
  const size_t ntiles = TilesPerImage;
  size_t tileidx;
  unsigned char *buffer = NULL;
  //const char format[] = "dumpets%04ld.%s";
  const char format[] = "dumpets%s.%s";
  char outname[512];
 
  long ref[3];
  ref[0] = startx;
  ref[1] = starty;
  ref[2] = 0;
 
  const struct tile *t = findtile( tiles, ntiles, ref );
  if( t )
      {
      assert( t->level == 0 );
      if( t->level == 0 )
        {
        tile_print( t, stdout );
        fseek( stream, t->offset, SEEK_SET );
        buffer = realloc(buffer, t->numbytes );
        fread( buffer, 1, t->numbytes, stream );
 
        const char *ext = ets_header_getcomp( &eh );
        sprintf( outname, format, "image", ext );
        FILE * out = fopen( outname, "wb" );
        fwrite( buffer, 1, t->numbytes, out );
        fclose( out );
        fprintf( stdout, "tile: %s\n", outname );
        }
      }
  else
      {
      // need to make a fake tile
      //fprintf( stdout, "Empty tile %u!\n", tileidx );
      fprintf( stdout, "Empty tile");
      }
 
 
 
  // cleanup
  //free( buffer );
  free( tiles );
  fclose( stream );
 
  return 0;
}

Voici le code python qui fait appel au fichier compilé à l'aide de ctypes.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
import ctypes
import numpy
import os
 
zelib = ctypes.CDLL(os.path.join(os.getcwd(),"ZeLib.so"))
res = zelib.main(os.path.join(os.getcwd(),"frame_t1.ets").encode('utf8'),70,173)
print(res)
Merci d'avance aux membres qui prendront le temps de regarder mon problème.