subtitles.cpp 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  1. #include "subtitles.h"
  2. Subtitles::Subtitles(const char *filename)
  3. {
  4. m_frame_based=0;
  5. m_last_sub=-1;
  6. m_font_size_mod=0;
  7. #ifdef SUBTITLES_READER
  8. if(!filename) return;
  9. IDataReader *file_reader=CreateReader(filename);
  10. if(file_reader) {
  11. char *text=NULL;
  12. int textpos=0;
  13. int allocsize=0;
  14. char buf[1024] = {0};
  15. unsigned aborttime=GetTickCount()+20000;
  16. for (;;)
  17. {
  18. int l=file_reader->read(buf,1024);
  19. if (l <= 0)
  20. {
  21. if (file_reader->iseof()) break;
  22. if (file_reader->geterror() || GetTickCount() > aborttime)
  23. {
  24. free(text);
  25. return;
  26. }
  27. Sleep(100);
  28. }
  29. else
  30. {
  31. if (textpos+l+1 >= allocsize)
  32. {
  33. allocsize = textpos+l+1+8192;
  34. text=(char*)realloc(text,allocsize);
  35. }
  36. memcpy(text+textpos,buf,l);
  37. textpos+=l;
  38. }
  39. }
  40. if (text) {
  41. text[textpos]=0;
  42. //fucko: check for case
  43. if(strstr(filename,".srt")) decodeSrtFile(text);
  44. else if(strstr(filename,".sub")) decodeSubFile(text);
  45. free(text);
  46. }
  47. }
  48. delete(file_reader);
  49. #endif
  50. }
  51. #ifdef SUBTITLES_READER
  52. void Subtitles::decodeSrtFile(char *text) {
  53. // parse subtitle file (.srt format)
  54. char *p=text;
  55. //for(int i=0;;i++) {
  56. while(1) {
  57. unsigned int time_start,time_end;
  58. // parse title nb
  59. char *p2=p;
  60. while(*p2 && *p2!='\n') p2++;
  61. *p2++=0;
  62. //if(atoi(p)!=i+1) break;
  63. if(atoi(p)<=0) break;
  64. // parse start time
  65. p=p2;
  66. while(*p2 && *p2!=' ') p2++;
  67. *p2++=0;
  68. time_start=getTimeFromSrtText(p);
  69. // parse "-->"
  70. while(*p2 && *p2!=' ') p2++;
  71. p2++;
  72. // parse end time
  73. p=p2;
  74. while(*p2 && *p2!='\n') p2++;
  75. *p2++=0;
  76. time_end=getTimeFromSrtText(p);
  77. // parse text
  78. p=p2;
  79. while(*p2 && !(*p2=='\r' || *p=='\n')) {
  80. while(*p2 && *p2!='\n') p2++;
  81. p2++;
  82. }
  83. *p2++=0;
  84. //remove trailing CR
  85. {
  86. int l=strlen(p);
  87. if(l) {
  88. if(p[l-1]=='\r' || p[l-1]=='\n') p[l-1]=0;
  89. }
  90. }
  91. m_subs.put(new SubsItem(time_start,time_end,p));
  92. if(*p2=='\n') p2++;
  93. p=p2;
  94. }
  95. m_frame_based=0;
  96. }
  97. unsigned int Subtitles::getTimeFromSrtText(const char *text) {
  98. int hours,mins,secs,mills;
  99. const char *p=text;
  100. hours=atoi(p);
  101. while(*p && *p!=':') p++;
  102. p++;
  103. mins=atoi(p);
  104. while(*p && *p!=':') p++;
  105. p++;
  106. secs=atoi(p);
  107. while(*p && *p!=',') p++;
  108. p++;
  109. mills=atoi(p);
  110. return mills+(secs*1000)+(mins*60000)+(hours*60*60000);
  111. }
  112. void Subtitles::decodeSubFile(char *text)
  113. {
  114. char *p=text;
  115. while(*p=='{') {
  116. int framestart,frameend;
  117. p++;
  118. char *p2=p;
  119. while(*p2 && *p2!='}') p2++;
  120. *p2++=0;
  121. framestart=atoi(p);
  122. p2+=1;
  123. p=p2;
  124. while(*p2 && *p2!='}') p2++;
  125. *p2++=0;
  126. frameend=atoi(p);
  127. p=p2;
  128. while(*p2 && *p2!='\r' && *p2!='\n') {
  129. //replace pipes with CR
  130. if(*p2=='|') *p2='\n';
  131. p2++;
  132. }
  133. *p2++=0;
  134. m_subs.put(new SubsItem(framestart,frameend,p));
  135. if(*p2=='\n') p2++;
  136. p=p2;
  137. }
  138. m_frame_based=1;
  139. }
  140. #endif
  141. SubsItem *Subtitles::getSubtitle(unsigned int time, unsigned int frame)
  142. {
  143. unsigned int ref=m_frame_based?frame:time;
  144. //check with lastsub
  145. if(m_last_sub!=-1) {
  146. SubsItem *item=m_subs.get(m_last_sub);
  147. if(ref>=item->timestart && ref<=item->timeend)
  148. {
  149. item->fontSize=item->origFontSize+m_font_size_mod;
  150. return item;
  151. }
  152. SubsItem *item2=m_subs.get(m_last_sub+1);
  153. if(item2) {
  154. if(ref>=item->timeend && ref<=item2->timestart) return NULL;
  155. if(ref>=item2->timestart && ref<=item2->timeend) {
  156. m_last_sub++;
  157. item2->fontSize=item2->origFontSize+m_font_size_mod;
  158. return item2;
  159. }
  160. }
  161. }
  162. int l= (int)m_subs.getlen();
  163. for(int i=0;i<l;i++) {
  164. SubsItem *item=m_subs.get(i);
  165. if(ref<item->timestart) break;
  166. if(ref>=item->timestart && ref<=item->timeend) {
  167. m_last_sub=i;
  168. item->fontSize=item->origFontSize+m_font_size_mod;
  169. return item;
  170. }
  171. }
  172. m_last_sub=-1;
  173. return NULL;
  174. }
  175. void Subtitles::addSubtitlePacket(SUBTITLE_INFO *sti)
  176. {
  177. m_frame_based=1; //FUCKO: put this in subsitem struct
  178. SubsItem *i=new SubsItem(sti->start_frame,sti->end_frame,sti->utf8_text);
  179. i->xPos=sti->xPos;
  180. i->yPos=sti->yPos;
  181. i->colorBlue=sti->colorBlue;
  182. i->colorGreen=sti->colorGreen;
  183. i->colorRed=sti->colorRed;
  184. i->extraDataSize=sti->extraDataSize;
  185. i->origFontSize=sti->fontSize;
  186. if(sti->extraDataSize) {
  187. i->extraData=malloc(sti->extraDataSize);
  188. memcpy((void *)i->extraData,sti->extraData,sti->extraDataSize);
  189. }
  190. i->muxed_subtitle=1;
  191. m_subs.put(i);
  192. }