id3_frame_render.cpp 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. // The authors have released ID3Lib as Public Domain (PD) and claim no copyright,
  2. // patent or other intellectual property protection in this work. This means that
  3. // it may be modified, redistributed and used in commercial and non-commercial
  4. // software and hardware without restrictions. ID3Lib is distributed on an "AS IS"
  5. // basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
  6. //
  7. // The ID3Lib authors encourage improvements and optimisations to be sent to the
  8. // ID3Lib coordinator, currently Dirk Mahoney ([email protected]). Approved
  9. // submissions may be altered, and will be included and released under these terms.
  10. //
  11. // Mon Nov 23 18:34:01 1998
  12. // improved/optimized/whatever 10/30/00 JF
  13. #include <string.h>
  14. #include <memory.h>
  15. #include "id3_tag.h"
  16. #include "id3_misc_support.h"
  17. luint ID3_Frame::Render (uchar *buffer)
  18. {
  19. luint bytesUsed = 0;
  20. ID3_FrameHeader header;
  21. ID3_FrameDef *info;
  22. luint flags;
  23. luint extras = 0;
  24. header.SetVersion (version, revision);
  25. bytesUsed += header.Size();
  26. // here is where we include things like
  27. // grouping IDs and crypto IDs
  28. if (strlen (encryptionID))
  29. {
  30. buffer[bytesUsed] = encryptionID[0];
  31. bytesUsed++, extras++;
  32. }
  33. if (strlen (groupingID))
  34. {
  35. buffer[bytesUsed] = groupingID[0];
  36. bytesUsed++, extras++;
  37. }
  38. /*
  39. if (version < 4)
  40. {
  41. // benski> set any UTF8 strings read from id3v2.4 to UTF-16,
  42. // so we can write with id3v2.3
  43. for (luint i = 0; i < numFields; i++)
  44. {
  45. if (fields[i]->flags & ID3FF_ADJUSTENC)
  46. {
  47. ID3_TextEnc enc= (ID3_TextEnc) Field(ID3FN_TEXTENC).Get();
  48. if (enc == ID3TE_UTF8 || enc == ID3TE_UTF16_BE)
  49. Field(ID3FN_TEXTENC).Set(ID3TE_UNICODE);
  50. }
  51. }
  52. }
  53. */
  54. // this call is to tell the string fields
  55. // what they should be rendered/parsed as
  56. // (ASCII or Unicode)
  57. UpdateStringTypes();
  58. for (luint i = 0; i < numFields; i++)
  59. {
  60. fields[i]->SetVersion (version, revision);
  61. bytesUsed += fields[i]->Render (&buffer[bytesUsed]);
  62. }
  63. // if we can compress frames individually and we
  64. // have been asked to compress the frames
  65. /*
  66. if (compression && version >= 3)
  67. {
  68. luint newFrameSize;
  69. uchar *newTemp;
  70. bytesUsed -= header.Size();
  71. newFrameSize = bytesUsed + (bytesUsed / 10) + 12;
  72. if (newTemp = new uchar[newFrameSize])
  73. {
  74. if (compress (newTemp, &newFrameSize, &buffer[header.Size() + extras], bytesUsed - extras) == Z_OK)
  75. {
  76. // if the compression actually saves space
  77. if ((newFrameSize + sizeof (luint)) < bytesUsed)
  78. {
  79. luint posn;
  80. int i;
  81. posn = header.Size();
  82. extras += sizeof (luint);
  83. memcpy (&buffer[posn + sizeof (luint)], newTemp, newFrameSize);
  84. for (i = 0; i < sizeof (luint); i++)
  85. buffer[posn + i] = (uchar) ((bytesUsed >> ((sizeof (luint) - i - 1) * 8)) & 0xFF);
  86. bytesUsed = newFrameSize + sizeof (luint);
  87. didCompress = true;
  88. }
  89. }
  90. else
  91. ID3_THROW (ID3E_zlibError);
  92. bytesUsed += header.Size();
  93. delete[] newTemp;
  94. }
  95. else
  96. ID3_THROW (ID3E_NoMemory);
  97. }
  98. */
  99. // perform any encryption here
  100. /* if (strlen (encryptionID))
  101. {
  102. }*/
  103. // determine which flags need to be set
  104. if (info = ID3_FindFrameDef (frameID))
  105. {
  106. bool didCompress = false;
  107. flags = 0;
  108. if (version == 4)
  109. {
  110. if (info->tagDiscard)
  111. flags |= ID3FL_TAGALTER_2_4;
  112. if (info->fileDiscard)
  113. flags |= ID3FL_FILEALTER_2_4;
  114. if (didCompress)
  115. flags |= ID3FL_COMPRESSION_2_4;
  116. if (strlen (encryptionID))
  117. flags |= ID3FL_ENCRYPTION_2_4;
  118. if (strlen (groupingID))
  119. flags |= ID3FL_GROUPING_2_4;
  120. }
  121. else
  122. {
  123. if (info->tagDiscard)
  124. flags |= ID3FL_TAGALTER_2_3;
  125. if (info->fileDiscard)
  126. flags |= ID3FL_FILEALTER_2_3;
  127. if (didCompress)
  128. flags |= ID3FL_COMPRESSION_2_3;
  129. if (strlen (encryptionID))
  130. flags |= ID3FL_ENCRYPTION_2_3;
  131. if (strlen (groupingID))
  132. flags |= ID3FL_GROUPING_2_3;
  133. }
  134. }
  135. else
  136. ID3_THROW (ID3E_InvalidFrameID);
  137. header.SetFrameID(frameID);
  138. header.SetFlags(flags);
  139. header.SetDataSize(bytesUsed - header.Size());
  140. header.Render(buffer);
  141. hasChanged = false;
  142. return bytesUsed;
  143. }