home *** CD-ROM | disk | FTP | other *** search
/ Planet Source Code Jumbo …e CD Visual Basic 1 to 7 / 4_2005-2006.ISO / data / Zips / Xiao_Stega1904516222005.psc / VB_Steg / ClsStegano.cls < prev    next >
Text File  |  2005-06-22  |  18KB  |  580 lines

  1. VERSION 1.0 CLASS
  2. BEGIN
  3.   MultiUse = -1  'True
  4.   Persistable = 0  'NotPersistable
  5.   DataBindingBehavior = 0  'vbNone
  6.   DataSourceBehavior  = 0  'vbNone
  7.   MTSTransactionMode  = 0  'NotAnMTSObject
  8. END
  9. Attribute VB_Name = "ClsStegano"
  10. Attribute VB_GlobalNameSpace = False
  11. Attribute VB_Creatable = True
  12. Attribute VB_PredeclaredId = False
  13. Attribute VB_Exposed = False
  14. Option Explicit
  15. '*************************************
  16. 'BMP Header Struct
  17. Private BmpHead As winBMPFileHeader
  18. Private BmpInfo As BITMAPINFOHEADER
  19. Private bmpPalette() As BITMAPPalette
  20. Private DeepColor&
  21. '*************************************
  22.  
  23. '*************************************
  24. 'BinaryAttach carried the data for each file added in binary format
  25. 'BinaryImg() carried tha data for the main image in binary format
  26. Dim BinaryAttach() As tBits, BinaryImg() As tBits
  27. 'bAttachdata carried the data for each file added in byte format
  28. 'bImgData() carried tha data for the main image in byte format
  29. Dim bImgData() As Byte, bAttachData() As Byte
  30. 'very hard to figure it out that?
  31. '*************************************
  32.  
  33. Dim mImageFile$ 'Image Filename
  34. Dim mOutputImageFile$ 'New Image Filename
  35.  
  36. Dim mFilesAdded& 'Count files added
  37. Dim OutFile& 'Pointer to file
  38. Dim mBytesLimit& 'Bytes limit to be added
  39. Dim mBytesAdded& 'Bytes to attach
  40.  
  41. Dim colFiles As Collection 'My files's collection
  42.  
  43. Dim cTAG() As Byte 'the main tag to identify if the file carried any file attached
  44.  
  45. Event StatusChanged(prcDone As Long, strStatus As String) 'Raise this event to notify what whe are doing
  46. Event SomeError(strDescription As String) 'Raise this event to notify when some error ocurr
  47.  
  48. ' NewEnum tiene que devolver la interfaz IUnknown del
  49. ' enumerador de una colecci≤n.
  50. Public Function NewEnum() As IUnknown
  51. Attribute NewEnum.VB_UserMemId = -4
  52.    Set NewEnum = colFiles.[_NewEnum]
  53. End Function
  54.  
  55. Public Property Get ImageFile() As String
  56.     ImageFile = mImageFile
  57. End Property
  58.  
  59. Public Property Let ImageFile(ByVal vNewValue As String)
  60.     mImageFile = vNewValue
  61.     mBytesLimit = FileLen(mImageFile) / 8
  62. End Property
  63.  
  64. Public Property Get FilesAdded() As Long
  65.     FilesAdded = mFilesAdded
  66. End Property
  67. 'AddFile
  68. 'strFile:the filename will be attach
  69. 'strTitle the Shortname fot this file, must be the same name with out the extension and the large path
  70. 'Key:the unique identify key for this file
  71. Public Function AddFile(strFile As String, strTitle As String, Key As String) As Boolean
  72. Dim tmpFile As ClsFile
  73. On Local Error GoTo AddErr
  74.     Set tmpFile = New ClsFile
  75.     'fill data
  76.     If FileExist(strFile) Then
  77.         With tmpFile
  78.             .KeyFile = Key
  79.             .FileName = strFile
  80.             .FileTitle = strTitle
  81.             .LenBytes = FileLen(strFile) 'get len in bytes
  82.             .TypeFile = VBA.Right$(strFile, 3) 'get type. (.exe,.txt,.bmp...)
  83.             
  84.             mBytesAdded = mBytesAdded + .LenBytes
  85.             If mBytesAdded > mBytesLimit Then 'if the files to attach is too long, can't be carried
  86.                 mBytesAdded = mBytesAdded - .LenBytes
  87.                 Err.Raise 9001, "AddFile", "The File can't be add. Too long to be attach!"
  88.             End If
  89.         End With
  90.         
  91.     End If
  92.     colFiles.Add tmpFile, Key
  93.     mFilesAdded = mFilesAdded + 1
  94.     AddFile = True
  95. Exit Function
  96. AddErr:
  97.     RaiseEvent SomeError(Err.Description & " in " & Err.Source)
  98. End Function
  99.  
  100. Public Function RemoveFile(Key As String) As Boolean
  101. On Local Error GoTo AddErr
  102. Dim tmpFile As ClsFile
  103.     Set tmpFile = colFiles(Key) 'remove form the collection the file added
  104.     mBytesAdded = mBytesAdded - tmpFile.LenBytes 'rest the bytes added too
  105.     Set tmpFile = Nothing 'Free memory
  106.     colFiles.Remove Key 'remove item
  107.     RemoveFile = True
  108.     mFilesAdded = mFilesAdded - 1
  109. Exit Function
  110. AddErr:
  111.     RaiseEvent SomeError(Err.Description)
  112.     Err.Clear
  113. End Function
  114.  
  115. Public Function GetFile(Key As String) As ClsFile
  116. Attribute GetFile.VB_UserMemId = 0
  117. On Local Error GoTo GetErr
  118.     Set GetFile = colFiles(Key) 'return info about any file added
  119. Exit Function
  120. GetErr:
  121.     RaiseEvent SomeError(Err.Description)
  122.     Err.Clear
  123. End Function
  124.  
  125. Private Sub Class_Initialize()
  126.     Set colFiles = New Collection
  127.     cTAG() = StrConv("TAG:Int21", vbFromUnicode)
  128. End Sub
  129.  
  130. Public Function EncodeIt() As Boolean
  131. On Local Error GoTo EncodeErr
  132.     
  133.     If FileExist(mImageFile) Then 'Validate filename exist
  134.         
  135.         
  136.         Dim tmpPalette As BITMAPPalette ' To calculate len of struct
  137.     
  138.         'Process data Image
  139.         Call ReadImg_
  140.         'convert image data to binary
  141.         Call Convert2BinaryArray_(bImgData(), BinaryImg())
  142.         
  143.         DoEvents
  144.  
  145.         RaiseEvent StatusChanged(0, "Preparing data to be write...")
  146.         
  147.         OutFile = FreeFile 'The Main Buffer file
  148.         'in this files we going to put all the data, TAG, and each file added
  149.         Open "c:\tmp_C23F41AA.dat" For Binary As #OutFile
  150.             
  151.             Put #OutFile, , cTAG()
  152.             Put #OutFile, , mFilesAdded
  153.             
  154.             RaiseEvent StatusChanged(0, "Please Wait...")
  155.             ReadAttach_
  156.             
  157.         Close #OutFile
  158.         
  159.         ConvertAttach_
  160.         Join_Img_Files_
  161.         
  162.         Kill "c:\tmp_C23F41AA.dat" 'delete buffer file
  163.         
  164.         RaiseEvent StatusChanged(100, "Encode done!")
  165.         
  166.     Else
  167.         RaiseEvent SomeError("File doesn't exist") 'Dumb !!
  168.     End If
  169.     
  170. Exit Function
  171. EncodeErr:
  172.     RaiseEvent SomeError(Err.Description)
  173.     Err.Clear
  174.     Close
  175. End Function
  176.  
  177. Public Function DecodeIt() As Boolean
  178.     If Not ReadTag_ Then 'Look for tag
  179.         RaiseEvent SomeError("The selected image no contain any data to extract or haven't a Xiao format")
  180.     Else
  181.         ExtractData_
  182.         DecodeIt = True 'return successful
  183.     End If
  184. End Function
  185.  
  186. Public Sub Save2Image()
  187. Dim strDone$
  188. If OutputImageFile <> "" Then
  189.     
  190.     RaiseEvent StatusChanged(0, "Saving file...")
  191.     
  192.     If Not SaveImg_() Then strDone = "Some error saving to new image" Else strDone = "Files was saved!"
  193.     RaiseEvent StatusChanged(100, strDone)
  194.     
  195. Else
  196.         RaiseEvent StatusChanged(0, "Image to save not was found!")
  197. End If
  198.     
  199. End Sub
  200.  
  201. Private Function SaveImg_() As Boolean
  202. Dim I&, J&, xFil&, lngCounter&
  203. Dim maxArr&
  204. On Local Error GoTo SaveImgErr
  205.     'save to new file in disc our image with the file added
  206.     maxArr = UBound(bImgData()) 'get max data image
  207.     
  208.     For J = 0 To UBound(BinaryImg()) 'Len image in binary format, must be equal LenImageInBytes * 8
  209.         
  210.         bImgData(I) = Bin2Asc(BinaryImg(J)) 'Convert the binary data to byte, 11111111 = 255
  211.         
  212.         I = I + 1
  213.         
  214.         If I > maxArr Then
  215.             Exit For
  216.         End If
  217.             
  218.         RaiseEvent StatusChanged(J * 100 / maxArr, "Saving new image...")
  219.             
  220.         DoEvents
  221.     Next J
  222.     
  223.     xFil = FreeFile 'prepare our file to be write
  224.     Open mOutputImageFile For Binary As #xFil
  225.         Put #xFil, , BmpHead 'write header 1st
  226.         Put #xFil, , BmpInfo '2th, write info
  227.         'write the image data with the files hiden
  228.         For lngCounter = 1 To DeepColor 'if exist..write palette data
  229.             Put #1, , bmpPalette(lngCounter)
  230.         Next lngCounter
  231.         
  232.         Put #xFil, , bImgData 'finally write the new data with our hide data
  233.         
  234.     Close #xFil 'end of the magic....=)
  235.     SaveImg_ = True
  236. Exit Function
  237. SaveImgErr:
  238.     RaiseEvent SomeError(Err.Description)
  239.     Err.Clear
  240. End Function
  241.  
  242. Private Sub ReadAttach_()
  243. Dim xFil&, I&, lenBy&
  244. Dim It As ClsFile
  245. Dim vData() As Byte, strOut() As Byte
  246. Dim Str3 As String * 3, Str10 As String * 10
  247. Dim strShort$
  248. On Local Error GoTo ReadAttachErr
  249.     
  250. xFil = FreeFile
  251. 'Read attach file
  252. RaiseEvent StatusChanged(0, "Reading file to attach...")
  253. I = 0
  254. For Each It In colFiles 'read the files added in the image
  255.     Open It.FileName For Binary As #xFil ' for each file added, build a new temp file in disc
  256.         
  257.         vData = InputB(LOF(xFil), #xFil)
  258.         
  259.         Str3 = It.TypeFile 'txt, bmp, jpg, gif, png
  260.         Str10 = It.FileTitle 'the short name
  261.         
  262.         I = I + 1
  263.         RaiseEvent StatusChanged((I * 100 / mFilesAdded), "Reading file to attach..." & Str10)
  264.         
  265.         strOut() = StrConv(Str3, vbFromUnicode)
  266.         Put #OutFile, , strOut()
  267.         Put #OutFile, , It.LenBytes
  268.         strOut() = StrConv(Str10, vbFromUnicode)
  269.         Put #OutFile, , strOut()
  270.         
  271.         Put #OutFile, , vData()
  272.         
  273.         
  274.         DoEvents
  275.     Close #xFil
  276. Next
  277. Exit Sub
  278. ReadAttachErr:
  279. RaiseEvent SomeError(Err.Description)
  280. Err.Clear
  281. End Sub
  282.  
  283. Private Sub ReadHeadImg_(pFile&)
  284. Dim tmpPalette As BITMAPPalette
  285. Dim I&
  286.     'teh 1st step is read al header for the bitmap, and skip it, to going directly to the image data
  287.     Get #pFile, , BmpHead 'fill head struct
  288.     Get #pFile, , BmpInfo 'fill info struct
  289.     
  290.     'calculate deepcolor
  291.     DeepColor = ((BmpHead.lngBitmapOffset - 54) / Len(tmpPalette))
  292.         
  293.     If DeepColor > 0 Then ReDim bmpPalette(1 To DeepColor) 'Rezise
  294.     
  295.     For I = 1 To DeepColor
  296.         Get #pFile, , bmpPalette(I)
  297.      Next I
  298.     
  299. End Sub
  300.  
  301. Private Sub ReadImg_()
  302. Dim xFil&, LenBytes&, lngCounter&
  303. Dim bytColor As Byte
  304.  
  305. 'Read the Img File
  306. xFil = FreeFile
  307. Open mImageFile For Binary As #xFil
  308.  
  309.     RaiseEvent StatusChanged(0, "Reading Header...")
  310.     
  311.     ReadHeadImg_ xFil
  312.     
  313.     'Calculate len image data, without headers
  314.     ReDim bImgData(0 To (BmpHead.lngFileSize - BmpHead.lngBitmapOffset) - 1)
  315.     
  316.     RaiseEvent StatusChanged(0, "Reading Image Data...")
  317.     
  318.     LenBytes = UBound(bImgData())
  319.     
  320.     For lngCounter = 0 To LenBytes ' this is the data where we going to hide our files
  321.         If Not EOF(xFil) Then
  322.             Get #xFil, , bytColor 'Read each rgb byte info
  323.             bImgData(lngCounter) = bytColor
  324.         End If
  325.         
  326.         RaiseEvent StatusChanged(lngCounter * 100 / LenBytes, "Reading Image Data...")
  327.         
  328.         DoEvents
  329.     Next lngCounter
  330.     
  331. 'ReadImg = DatImg()
  332. Close #xFil
  333.     
  334. End Sub
  335. 'Look for our tag in the image file, if doesn't exist skip all
  336. Private Function ReadTag_() As Boolean
  337. Dim binData() As tBits, binTag() As tBits
  338. Dim I&, J&, Cur&, bytColor As Byte
  339. Dim strMyTag As String * 9
  340. Dim lenStruct&, xFil&
  341. Dim xyTb(0) As tBits
  342.     
  343.     RaiseEvent StatusChanged(0, "Searching header...")
  344.     
  345.     lenStruct = 9 'the len for the tag is always 9 bytes
  346.     ReDim binTag(0 To lenStruct)
  347.     
  348.     xFil = FreeFile
  349.     Open mImageFile For Binary As #xFil
  350.         
  351.         ReadHeadImg_ xFil  'Read header for bitmap
  352.         
  353.         lenStruct = 72 '8 bytes = 1 extra-byte, TAG= 9 bytes * 8 bytes = 72 bytes
  354.         
  355.         ReDim bImgData(0 To lenStruct)
  356.         
  357.         For I = 0 To lenStruct
  358.             If Not EOF(xFil) Then
  359.                 Get #xFil, , bytColor
  360.                 bImgData(I) = bytColor
  361.             End If
  362.         Next I
  363.     
  364.     Close #xFil
  365.     
  366.     Call Convert2BinaryArray_(bImgData(), binData())
  367.     
  368.     lenStruct = UBound(binTag()) 'len data in binary
  369.     
  370.     Cur = 0
  371.     lenStruct = 9 'the len tag is alway 9bytes
  372.     For I = 0 To lenStruct
  373.         For J = 0 To 7
  374.             binTag(I).Bits(J) = binData(Cur).Bits(7)
  375.             Cur = Cur + 1
  376.             
  377.         Next J
  378.         If Cur >= 72 Then Exit For
  379.     Next I
  380.     
  381.     strMyTag = Binary2String(binTag)
  382.     
  383.     ReadTag_ = (strMyTag = "TAG:Int21")
  384.     
  385. End Function
  386.  
  387. Private Sub ExtractData_()
  388. Dim OutFile&, ImgFile&
  389. Dim tmpFile&
  390. Dim dataOut() As Byte
  391. Dim BinOut() As tBits
  392. Dim Bytes2Read&, Cur&, I&, J&
  393. Dim bytColor As Byte
  394. Dim sTAg$, lFA&, sTF$, lLF&, sNF$
  395.  
  396.     ImgFile& = FreeFile
  397.     
  398.     Open mImageFile$ For Binary As #ImgFile 'open the main image
  399.         
  400.         Call ReadHeadImg_(ImgFile)
  401.         'skip the bmp header, to get the real image data
  402.         Bytes2Read = LOF(ImgFile) - Loc(ImgFile)
  403.         
  404.         ReDim dataOut(0 To Bytes2Read)
  405.         For I = 0 To (Bytes2Read)
  406.             If Not EOF(ImgFile) Then
  407.                 Get #ImgFile, , bytColor
  408.                 dataOut(I) = bytColor
  409.             End If
  410.         Next I
  411.     Close #ImgFile
  412.  
  413.         Call Convert2BinaryArray_(dataOut(), BinaryImg())
  414.         
  415.         Bytes2Read = UBound(BinaryImg()) 'len image in binary
  416.         ReDim dataOut(0 To Bytes2Read)
  417.         ReDim BinOut(0 To Bytes2Read)
  418.         
  419.         Cur = 0
  420.         'we going to read the bytes 7 for each byte in the image data
  421.         'and put it in other array to extract the hide data
  422.         For I = 0 To (Bytes2Read)
  423.             For J = 0 To 7
  424.                 If Cur >= Bytes2Read Then Exit For
  425.                 BinOut(I).Bits(J) = BinaryImg(Cur).Bits(7)
  426.                 Cur = Cur + 1
  427.             Next J
  428.             dataOut(I) = Bin2Asc(BinOut(I)) 'convert the binary hide in bytes
  429.         Next I
  430.         
  431.         OutFile = FreeFile
  432.         Open "c:\tmp_DD2741C.dat" For Binary As #OutFile 'tmp file to read data
  433.             Put #OutFile, , dataOut()
  434.         Close OutFile
  435.         
  436.         OutFile = FreeFile
  437.         
  438.         Open "c:\tmp_DD2741C.dat" For Binary As #OutFile 'tmp file to read data
  439.             
  440.             sTAg = ExtractItem_(OutFile, 9, 0, 1) 'Read the main tag
  441.             lFA = ExtractItem_(OutFile, 4, 0, 0) 'read the number of files added
  442.             Dim strFile$
  443.             Dim It As ClsFile
  444.             For I = 1 To lFA
  445.                 sTF = ExtractItem_(OutFile, 3, 0, 1) 'Read the type file(txt,bmp,gif,jpg,png)
  446.                 lLF = ExtractItem_(OutFile, 4, 0, 0) 'read the len in bytes for this file
  447.                 sNF = ExtractItem_(OutFile, 10, 0, 1) 'read the short name for this file
  448.                 strFile = "c:\" & sNF & "DD2741C." & sTF 'build the buffer filename
  449.                 
  450.                 tmpFile = FreeFile
  451.                 Open strFile For Binary As tmpFile
  452.                     dataOut() = InputB(lLF, OutFile) 'read n-bytes, the len for this file
  453.                     Put tmpFile, , dataOut() 'write in disc
  454.                 Close tmpFile
  455.                 
  456.                 AddFile strFile, sNF, CStr("c0" & I) 'add in the class
  457.                 'mBytesAdded = mBytesAdded + lLF 'counter the bytes added in the image
  458.                 
  459.             Next
  460.         
  461.         Close OutFile
  462.         
  463.         Kill "c:\tmp_DD2741C.dat"
  464.         
  465.     
  466. End Sub
  467.  
  468. Private Function ExtractItem_(pFile As Long, Bytes2Read As Long, Bytes2Look As Long, RetType As Integer)
  469. Dim Memo() As Byte
  470. Dim lLong&
  471. Dim strEnd$
  472.     Memo() = InputB(Bytes2Read, pFile) 'read n-bytes from disc
  473.     
  474. If RetType = 0 Then 'Numeric
  475.     CopyMemory lLong, Memo(0), Len(lLong)
  476.     ExtractItem_ = lLong
  477. ElseIf RetType = 1 Then 'String
  478.     strEnd = Memo()
  479.     ExtractItem_ = StrConv(strEnd, vbUnicode)
  480. End If
  481.  
  482. End Function
  483.  
  484. Private Sub ConvertAttach_()
  485. Dim byt As Byte
  486. Dim LenF&, I&
  487. 'Read all files added and convert to binary
  488.     OutFile = FreeFile
  489.     LenF = FileLen("c:\tmp_C23F41AA.dat")
  490.     ReDim bAttachData(0 To LenF)
  491.     
  492.     Open "c:\tmp_C23F41AA.dat" For Binary As #OutFile
  493.         Do While Not EOF(OutFile)
  494.             Get OutFile, , byt
  495.             bAttachData(I) = byt
  496.             I = I + 1
  497.         Loop
  498.         
  499.     Close #OutFile
  500.  
  501.     Call Convert2BinaryArray_(bAttachData(), BinaryAttach())
  502.     
  503. End Sub
  504. 'the magic function, joing image and files to attach in only one file
  505. Private Sub Join_Img_Files_()
  506. Dim I&, J&, K&, LenImg&, LenF&
  507.     
  508.     LenImg = UBound(BinaryImg()) 'len in binary of image
  509.     LenF = UBound(BinaryAttach()) 'len in binary for files to attach
  510.     I = 0
  511.     
  512.     For J = 0 To LenF
  513.         For K = 0 To 7
  514.             BinaryImg(I).Bits(7) = BinaryAttach(J).Bits(K) 'put one bit from binary data to hide in the bit 7
  515.             I = I + 1
  516.         Next K
  517.         If I >= LenImg Then Exit For
  518.         RaiseEvent StatusChanged((I * 100 / LenImg), "Joining files with image...")
  519.         DoEvents
  520.     Next J
  521.     
  522. End Sub
  523. 'Convert2BinaryArray_
  524. 'Source(): the file data in bytes
  525. 'retArray(): the Binary data to be return
  526. Private Sub Convert2BinaryArray_(Source() As Byte, RetArray() As tBits)
  527. Dim LenArray&, I&
  528. Dim arrBinary() As tBits
  529. Dim Bits8 As tBits
  530.  
  531.     LenArray = UBound(Source())
  532.     
  533.      ReDim arrBinary(0 To LenArray)
  534.      
  535.      For I = 0 To LenArray
  536.         Bits8 = ByteToBinary(Source(I)) 'convert 1 byte to binary
  537.         arrBinary(I) = Bits8
  538.         RaiseEvent StatusChanged((I * 100 / LenArray), "Convert Hex to Binary...")
  539.         
  540.         DoEvents
  541.  
  542.      Next I
  543.  
  544. RetArray = arrBinary
  545.  
  546. End Sub
  547.  
  548. Private Function FileExist(strFile As String) As Boolean
  549. Dim Rs$, Tama As Boolean
  550. Dim Tm&
  551.     Rs = Dir(strFile)
  552.     FileExist = (Len(Rs))
  553. End Function
  554.  
  555. Public Property Get OutputImageFile() As String
  556.     OutputImageFile = mOutputImageFile
  557. End Property
  558.  
  559. Public Property Let OutputImageFile(ByVal sNewFile As String)
  560.     mOutputImageFile = sNewFile
  561. End Property
  562.  
  563. Private Sub Class_Terminate()
  564. Dim tmpClass As ClsFile
  565. For Each tmpClass In colFiles
  566.     Set tmpClass = Nothing
  567. Next
  568. Set colFiles = Nothing
  569. End Sub
  570.  
  571. Public Property Get BytesAdded() As Long
  572.     BytesAdded = mBytesAdded
  573. End Property
  574.  
  575.  
  576. Public Property Get BytesTotal() As Variant
  577.     BytesTotal = mBytesLimit
  578. End Property
  579.  
  580.