Newsgroup: it.comp.lang.c++
Titolo: Copiare porzioni di memoria (memcpy?)

Salve,
ho 2 strutture:
unsigned short origine[480][640];
unsigned short destinazione[480][640];
normalmente per copiare il contenuto di origine in destinazione uso:
memcpy((void*) destinazione, (void*) origine, sizeof(origine));
Mi chiedevo però se fosse possibile copiare solo una porzione 
dell'origine, partendo, ad esempio, dalle coordinate:
origine[100][200]
per finire a orgine[150][500]
E' possibile farlo con memcpy o bisogna farsi una funzione apposita?
saluti

 E' possibile farlo con memcpy o bisogna farsi una funzione apposita?
Puoi usare memcpy() ma non basta una sola chiamata: devi chiamarla
n volte perche' la memoria che devi copiare non e' in un  unico
blocco contiguo:
// non testato
// copia un blocco di 50 righe e 300 colonne
for(int i = 100; i < 150; i++ )
  memcpy( &dst[i][200], &src[i][200], (500-200) );
ciao
Giacomo

   memcpy( &dst[i][200], &src[i][200], (500-200) );
Grazie Giacomo,
avevo immaginato una roba del genere! ;)
saluti!

   memcpy( &dst[i][200], &src[i][200], (500-200) );
Ciao Giacomo,
sono partito dal Tuo esempio ed ho provato a realizzare una funzioncina 
ma ricavo solo un mare di errori:
void MemCopy(unsigned short* _dest, unsigned short _src,
  unsigned short _sz_x, unsigned short _sz_y,
  unsigned short _from_x,	unsigned short _from_y,
  unsigned short _to_x, unsigned short _to_y,
  unsigned char _size_of)
{
  for (unsigned short y = _from_y; y < _to_y; y++)
  {
   memcpy((void*) &(&_dest)[y][_from_x], (void*) &(&_src)[y][_from_x],
     _size_of * ((_to_x - _from_x) - 1));
  }
}
errori:
- warning: cast to pointer from integer of different size
- error: invalid types `short unsigned int[short unsigned int]' for 
array subscript
Se "aggiusto" da una parte sbaglio dall'altra! ;-)

/////////// CODICE COMPLETO:
void MemCopy(unsigned short* _dest, unsigned short* _src,
  unsigned short _sz_x, unsigned short _sz_y,
  unsigned short _from_x, unsigned short _from_y,
  unsigned short _to_x, unsigned short _to_y,
  unsigned char _size_of)
{
  for (unsigned short y = _from_y; y < _to_y; y++)
  {
   memcpy((void*) (&(&_dest)[y])[_from_x],
     (void*) (&(&_src)[y])[_from_x],
     _size_of * ((_to_x - _from_x) - 1));
  }
}
int main(void)
{
	unsigned short o[5][5];
	unsigned short d[5][5];
	for (int i = 0; i < 5; i++)
	{
		for (int j = 0; j < 5; j++)
		{
			o[i][j] = i;
			d[i][j] = 0;
		}
	}
	for (int i = 0; i < 5; i++)
	{
		for (int j = 0; j < 5; j++)
		{
			printf("%d - ", o[i][j]);
		}
		printf("\n");
	}
	printf("\n");
	printf("\n");
	printf("\n");
	unsigned short* dest = &d[0][0];
	unsigned short* orig = &o[0][0];
	MemCopy(
		dest,
		orig,
		5,
		5,
		0,
		0,
		5 + 1,
		5 + 1,
		sizeof(unsigned short));
	for (int i = 0; i < 5; i++)
	{
		for (int j = 0; j < 5; j++)
		{
			printf("%d - ", d[i][j]);
		}
		printf("\n");
	}
	return (0);
}
//////
in pratica sembra che la funzione copi gli elementi di o(orig) in 
d(dest) ma poi il programma crasha...non risco a capire......


Il problema e' che ti serve sapere anche quanto e' lunga una riga
del tuo array bidimensionale, altrimenti fai dei pasticci:
(&_dest)[y] corrisponde a _dest+y, ossia un ptr a lla y-esima
colonna della prima riga del tuo array.
&(&_dest)[y][_from_x] corrisponde a (_dest+y)+_from_x
ossia alla (y+_from_x)-esima colonna della prima riga del tuo
array.
Vedo due strade: o cambi la dichiarazione da
unsigned short* _dest
a
unsigned short* _dest[MAX_COLS]
ossia gli dici che e' un array di array, in questo modo
sai che _dest[1] punta alla giusta cella (colonna zero riga 1)
oppure per avere una gestione dinamica del numero di colonne
devi aggiungere un nuovo parametro alla funzione e
calcolare l'indirizzo della cella in questo modo:
(&_dest)[ y * num_colonne + _from_x ]
oppure, equivalente:
&_dest + ( y * num_colonne + _from_x )
ciao
Giacomo

 &_dest + ( y * num_colonne + _from_x )
Ciao Giacomo,
Ti ringrazio per la dritta, vedo cosa riesco a cavarci! ;-)
Grazie 1000!


prova con la seguente funzione template:
template<size_t _sz_y_dest, size_t _sz_x_dest, size_t _sz_y_src, size_t 
_sz_x_src>
void MemCopy(
	unsigned short (&_dest)[_sz_y_dest][_sz_x_dest],
	unsigned short (&_src)[_sz_y_src][_sz_x_src],
	unsigned short _from_x, unsigned short _from_y,
	unsigned short _to_x, unsigned short _to_y
	)
{
	for (unsigned short y = _from_y; y < _to_y; y++)
	{
		memcpy(&_dest[y][_from_x], &_src[y][_from_x], sizeof(short) * (_to_x - 
_from_x + 1));
	}
}
Per usarla, la chiamata dovrebbe essere:
MemCopy(d, o, 0, 0, 5, 5);

 MemCopy(d, o, 0, 0, 5, 5);
Che ficata! FUNZIONA!
GRAZIEEEE! ;-);-);-)



Se non si tratta di una insolita coincidenza che mi fa dire cretinate, 
di sicuro stai parlando di porzioni di memoria che contengono immagini - 
la cosa strana è che in tutte le funzioni di basso livello relative alla 
manipolazione delle immagini (che abbia mai incontrato) i dati vengono 
immagazzinati in un array normale e non in una matrice a due dimensioni. 
Normalmente (per la mia esperienza) ci si riferisce ai singoli pixel con 
roba del tipo [y * stride + x] e non con [y][x] - comunque, dettaglio a 
parte, è necessario l'utilizzo degli array C?
Stavo pensando che magari potresti immagazzinare le immagini all'interno 
di un std::valarray e approfittare di tutta una serie di operazioni 
ricorrenti nella loro manipolazione (tagli, doppi tagli per gestire 
sezioni dell'immagine - tipo le matrici che stai usando - maschere e 
così via).
-- 
FSC
http://userscripts.org/scripts/show/59948

 così via).
Ciao Francesco,
in effetti è proprio come dici, si tratta di immagini immagazzinate in 
array bidimensionali che si riferiscono a pixel, il tutto immagazzinato 
in aree di memoria. Purtroppo il tutto va gestito in maniera molto 
manuale con una versione striminzita delle funzioni normalmente presenti 
nel C++ su microprocessore PXA.
Un saluto e grazie,



Ah, interessante... si tratta di roba incorporata in un cellulare o roba 
del genere? Ho provato a fare una ricerca e sono andato a finire sui 
processori XScale di Intel... va be', non voglio andare fuori tema 
proprio al mio primo intervento.
Buon proseguimento :-)
-- 
FSC
http://userscripts.org/scripts/show/59948


ciao
Soviet

 ottimizzata per sfruttare le istruzioni single instruction-multiple data
Quella delle ottimizzazioni era una delle considerazioni, sì, l'altra 
era la (relativa) facilità d'uso, purtroppo ho scoperto che la questione 
originale di questo thread si sviluppa in ambito embedded, quindi, a 
quanto pare, niente lussi...
-- 
FSC
http://userscripts.org/scripts/show/59948

 proprio al mio primo intervento.
Centro 2 volte! ;-) Il processore è proprio un Marvel XScale PXA255 e la 
grafica va caricata in una flash a partire da un indirizzo specifico. 
Potendo gestire solo dati a 16bit le immagini vanno inizialmente 
convertite e compresse in formato RLE565. L'eseguibile viene caricato a 
parte e le immagini vanno decompresse nella RAM dinamica e spesso 
bisogna copiare porzioni dell'una o dell'altra sulla memoria video, da 
qui l'esigenza di avere una prospettiva XY dell'ordine dei singoli pixel 
in memoria.
Un saluto ancora,

Non è sufficiente la stdlib? 
http://cplusplus.com/reference/algorithm/copy/