I should have tried to run without suppressing errors. I think The Natural Philosopher is right about Chinese whispers, I used these options without looking into dd options carefully. Actually it's odd I used conv=noerror as I usually like to check for errors.
The conv=sync was also a bad idea as it fills out short inputs with zeroes. When I ran the restore without conv=noerror it gave me this warning: dd: warning: partial read (32768 bytes); suggest iflag=fullblock
So I think what it was doing was filling the rest of the block with zeroes on each partial read then writing the output. I also think the operation completed more quickly without this argument which would have been because it would have been reading only 32k then writing a whole
1M. However this is just an impression, I didn't time it.
The number of whispers saying the same thing misled me into assuming it was gold information. Damn Chinese! (joke - nothing against the Chinese). I was obviously a bit lazy.
So I tried the following lines which worked: # dd bs=1M count=3752 if=/dev/sdc | gzip -c >/backfile.img.gz # gunzip -c /backfile.img.gz | dd bs=1M count=3752 iflag=fullblock of=/dev/sdc
Actually it now strikes me that I should also use iflag=fullblock on the intial SD card read. Thinking about it, whenever you use a count it would seem that iflag=fullblock should always be used, otherwise the count is a count of read operations.
The reason for the block count is that the SD card I used was 16GB but the partitions were much smaller - about 3.8GB - so there was no point writing beyond this. Also if you read the whole SD card you'd get a much larger file unless you first filled the empty space with zeroes. I used a spreadsheet to check the figures reported by fdisk. There were 2 partitions but the first started 4MB into the card.
So problem solved, thanks for all the replies.
Final solution: # dd bs=1M count=3752 iflag=fullblock if=/dev/sdc | gzip -c >/backfile.img.gz # gunzip -c /backfile.img.gz | dd bs=1M count=3752 iflag=fullblock of=/dev/sdc