assert(len - read >= 3);
int cid, clen; read += Get_chunk_header(in, cid, clen);
static int Read_material_chunk	(	Model3d *model,	istream& in, 			// Header already read.	int top_len,			// Total length of this chunk.	Material *mat	)	{	int top_read = CHUNK_HEADER_LENGTH;	// Already read header.	while (top_read < top_len)	// Go through subchunks.		{		int id, len;		int read = Get_chunk_header(in, id, len);		switch (id)			{		case MATNAME:		// Material name.			{			string name;			read += Get_string(in, name);			mat->set_name(name.c_str());			// ++++++There are more bytes.  For now:			in.seekg(len - read, ios::cur);	//+++++++			read = len;	//++++++skip to end.			break;			}		case MATAMBIENT:	//+++++++Unsure.  Fall through.		case MATDIFFUSE:	// Color.			{			assert(len - read >= 3);			unsigned char c[3];			in.read(c, 3);			read += 3;			mat->set_color(&c[0]);			// ++++++There are more bytes.  For now:			in.seekg(len - read, ios::cur);	//+++++++			read = len;	//++++++skip to end.			break;			}		case MATMAP:		// Parent of texture info.			{			int subread = Read_material_chunk(model, in, len, mat);			if (subread < 0)				return subread;			read += subread;			break;			}		case MATMAPFILE:	// Texture filename.			{			string name;			read += Get_string(in, name);			mat->set_texture_filename(name.c_str());			assert(read == len);			break;			}		default:		// Don't care.			cerr << "3ds id 0x" << hex << id << " skipped" << endl;			in.seekg(len - read, ios::cur);			read = len;			break;			}		top_read += read;	// Add to top's total.		}	return in.good() ? (top_read - CHUNK_HEADER_LENGTH) : -1;	}