Index: video.c
===================================================================
--- video.c	(revision 58)
+++ video.c	(revision 59)
@@ -0,0 +1,225 @@
+/*
+    Raydium - CQFD Corp.
+    http://raydium.cqfd-corp.org
+    License: GPL - GNU General Public License, see "gpl.txt" file.
+*/
+
+#ifndef DONT_INCLUDE_HEADERS
+#include "index.h"
+#else
+#include "headers/video.h"
+#endif
+
+#include "video.h"
+    
+
+void raydium_video_init(void)
+{
+int i;
+
+for(i=0;i<RAYDIUM_MAX_VIDEOS;i++)
+    {
+    raydium_video_video[i].state=0;
+    }
+
+}
+
+signed char raydium_video_isvalid(int i)
+{
+if(i>=0 && i<RAYDIUM_MAX_VIDEOS &&
+    raydium_video_video[i].state)
+	return 1;
+return 0;
+
+}
+
+int raydium_video_find_free(void)
+{
+int i;
+
+for(i=0;i<RAYDIUM_MAX_VIDEOS;i++)
+    if(!raydium_video_video[i].state)
+	return i;
+return -1;
+}
+
+
+int raydium_video_find(char *name)
+{
+int live,i;
+
+live=raydium_live_texture_find(raydium_texture_find_by_name(name));
+
+
+for(i=0;i<RAYDIUM_MAX_VIDEOS;i++)
+    if(raydium_video_video[i].state &&
+       raydium_video_video[i].live_id==live)
+	return i;
+
+return -1;
+}
+
+void raydium_video_jpeg_decompress(FILE *fp,unsigned char *to)
+{
+struct jpeg_decompress_struct cinfo;
+struct jpeg_error_mgr jerr;
+JSAMPARRAY buffer;
+int row_stride;
+long count;
+
+cinfo.err=jpeg_std_error(&jerr);
+jpeg_create_decompress(&cinfo);
+jpeg_stdio_src(&cinfo, fp);
+jpeg_read_header(&cinfo, TRUE);
+jpeg_start_decompress(&cinfo);
+
+row_stride = cinfo.output_width * cinfo.output_components;
+buffer = (*cinfo.mem->alloc_sarray)
+	((j_common_ptr) &cinfo, JPOOL_IMAGE, row_stride, 1);
+
+count=cinfo.output_height-1;
+while (cinfo.output_scanline < cinfo.output_height) 
+    {
+    jpeg_read_scanlines(&cinfo, buffer, 1);
+    memcpy(to+cinfo.image_width*cinfo.output_components*(cinfo.output_height-count-1),buffer[0],row_stride);
+    count--;
+    }
+jpeg_finish_decompress(&cinfo);
+jpeg_destroy_decompress(&cinfo);
+}
+
+
+int raydium_video_open(char *filename, char *as)
+{
+int id;
+char head[100];
+int head_end;
+int i,j,c;
+
+id=raydium_video_find_free();
+
+if(id<0)
+    {
+    raydium_log("video: ERROR no more free slot (%i max)",filename,RAYDIUM_MAX_VIDEOS);
+    return -1;
+    }
+
+raydium_video_video[id].fp=raydium_file_fopen(filename,"rb");
+
+if(!raydium_video_video[id].fp)
+    {
+    raydium_log("video: ERROR: file '%s': open failed",filename);
+    return -1;
+    }
+
+fread(head,90,1,raydium_video_video[id].fp);
+head_end=0;
+for(i=0;i<90;i++)
+    if(head[i]=='|')
+	{
+	head_end=i;
+	break;
+	}
+
+if(!head_end)
+    {
+    fclose(raydium_video_video[id].fp);
+    raydium_log("video: ERROR: file '%s': invalid header or not a JPGS file. see docs",filename);
+    return -1;
+    }
+
+head[head_end]=0;
+fseek(raydium_video_video[id].fp,head_end+1,SEEK_SET);
+
+sscanf(head,"%i %i %i %i",
+&raydium_video_video[id].fps,
+&raydium_video_video[id].sizex,
+&raydium_video_video[id].sizey,
+&raydium_video_video[id].frames_total);
+
+raydium_video_video[id].state=1;
+raydium_video_video[id].elapsed=0;
+raydium_video_video[id].data=malloc(raydium_video_video[id].sizex*raydium_video_video[id].sizey*3);
+
+raydium_video_video[id].live_id=raydium_live_texture_create(as,raydium_video_video[id].data,raydium_video_video[id].sizex,raydium_video_video[id].sizey,24);
+
+raydium_video_video[id].offsets=malloc(sizeof(long)*raydium_video_video[id].frames_total);
+for(i=0;i<raydium_video_video[id].frames_total;i++)
+    {
+    head[0]=0;
+    j=0;
+    while((c=fgetc(raydium_video_video[id].fp))!='|')
+	{
+	head[j++]=c;
+	head[j]=0;
+	}
+    raydium_video_video[id].offsets[i]=atol(head);
+    }
+
+raydium_video_video[id].start=ftell(raydium_video_video[id].fp);
+raydium_video_video[id].last_decoded=-1;
+
+raydium_log("video: %s (%i) as live texture %s (%i), %ix%i %i fps (%i frames)",
+filename,id,as,raydium_video_video[id].live_id,
+raydium_video_video[id].sizex,raydium_video_video[id].sizey,
+raydium_video_video[id].fps,
+raydium_video_video[id].frames_total);
+
+return id;
+}
+
+
+void raydium_video_callback_video(int id)
+{
+int current;
+raydium_video_video[id].elapsed+=raydium_frame_time;
+
+current=raydium_video_video[id].elapsed*raydium_video_video[id].fps;
+
+if(current>=raydium_video_video[id].frames_total)
+    {
+    raydium_video_video[id].elapsed=0;
+    current=0;
+    }
+
+if(current==raydium_video_video[id].last_decoded)
+    {
+    //printf("not again\n");
+    return;
+    }
+
+fseek(raydium_video_video[id].fp,raydium_video_video[id].start+raydium_video_video[id].offsets[current],SEEK_SET);
+raydium_video_jpeg_decompress(raydium_video_video[id].fp,raydium_video_video[id].data);
+
+raydium_video_video[id].last_decoded=current;
+raydium_live_texture_refresh(raydium_video_video[id].live_id);
+}
+
+void raydium_video_callback(void)
+{
+int i;
+
+for(i=0;i<RAYDIUM_MAX_VIDEOS;i++)
+    if(raydium_video_video[i].state)
+	{
+	raydium_video_callback_video(i);
+	}
+}
+
+void raydium_video_delete(int id)
+{
+if(!raydium_video_isvalid(id))
+    {
+    raydium_log("video: ERROR: cannot delete video, invalid index");
+    return;
+    }
+fclose(raydium_video_video[id].fp);
+free(raydium_video_video[id].offsets);
+free(raydium_video_video[id].data);
+raydium_video_video[id].state=0;
+}
+
+void raydium_video_delete_name(char *name)
+{
+raydium_video_delete(raydium_video_find(name));
+}