Jump to content

Identify SQLite BLOB Image Format


NiVZ
 Share

Recommended Posts

Just wanted to add one final thanks for all the help I got in this thread. Spent a few hours tonight making a GUI and added in the read and write image stuff you guys helped me with. The project was to change the video thumbnails on my 4 year old daughter's toy so she can recognise the videos from the pictures. The built in software was taking the first frame which more often than not was black. The help you guys gave me means I've now replaced these with more identifiable pictures (dvd covers, etc) Going to have one very happy daughter in the morning.

NiVZ

post-34043-0-59442500-1332546277_thumb.j

post-34043-0-94907800-1332546288_thumb.j

Link to comment
Share on other sites

Congratulations. Now you can start improving the script. From the code snippets I have seen, there are missing calls to Release and destroy functions. If you use the application for some time, the memory leaks wil result in unnecesary high memory consumption.

*GERMAN* [note: you are not allowed to remove author / modified info from my UDFs]My UDFs:[_SetImageBinaryToCtrl] [_TaskDialog] [AutoItObject] [Animated GIF (GDI+)] [ClipPut for Image] [FreeImage] [GDI32 UDFs] [GDIPlus Progressbar] [Hotkey-Selector] [Multiline Inputbox] [MySQL without ODBC] [RichEdit UDFs] [SpeechAPI Example] [WinHTTP]UDFs included in AutoIt: FTP_Ex (as FTPEx), _WinAPI_SetLayeredWindowAttributes

Link to comment
Share on other sites

There is one thing for sure: you take good care of her!

I whish all kids would have such a loving father.

This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.
Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe here
RegExp tutorial: enough to get started
PCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta.

SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.
SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.
An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.
SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)
A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!
SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt)

Link to comment
Share on other sites

Thanks jchd :oops:

I notice a lot of parents are looking to be able to do this as it is a very popular device (last christmas must have toy) and the age range means not all children can read making it more difficult to use independently.

Once i polish the script up a bit i'd be happy to share for free but not sure if there are any legal implications since this is a commercial toy. Although the database and videos are stored on an SD card (which does.not come with the toy)

Anyone have any experience of doing anything like this? Don't want to get in trouble for reverse engineering :bye: The company's tech support are pretty good so i might run it past them.

NiVZ

Edited by NiVZ
Link to comment
Share on other sites

I see nothing close to reverse engineering nor anything that the maker could decently object against.

SQLite is public domain and reading the data on user-supplied SD can't be called a big fraud.

This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.
Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe here
RegExp tutorial: enough to get started
PCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta.

SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.
SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.
An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.
SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)
A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!
SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt)

Link to comment
Share on other sites

I see nothing close to reverse engineering nor anything that the maker could decently object against.

SQLite is public domain and reading the data on user-supplied SD can't be called a big fraud.

Even the image format can be generated with native windows api.

*GERMAN* [note: you are not allowed to remove author / modified info from my UDFs]My UDFs:[_SetImageBinaryToCtrl] [_TaskDialog] [AutoItObject] [Animated GIF (GDI+)] [ClipPut for Image] [FreeImage] [GDI32 UDFs] [GDIPlus Progressbar] [Hotkey-Selector] [Multiline Inputbox] [MySQL without ODBC] [RichEdit UDFs] [SpeechAPI Example] [WinHTTP]UDFs included in AutoIt: FTP_Ex (as FTPEx), _WinAPI_SetLayeredWindowAttributes

Link to comment
Share on other sites

Hello,

Here is my finished script. I'd appreciate any comments you guys could give me. I could have probably combined the reading/writing functions a bit more. I would have also liked to be able to handle using cursor up and cursor down on the listview update the preview image. And I could have added error checking to the SQLite Exec read and write queries.

To test this version you'll need to create a folder called 'LLN' in root of C: and uncomment line 33. And rename previously attached videos.db to videosinfo.db and put it in C:\LLN.

Credit given to Prog@ndy for the functions and thanked both Prog@ndy and jchd in the 'About' box ;o)

NiVZ

#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <StaticConstants.au3>
#include <GuiListView.au3>
#include <WinApi.au3>
#include <SQLite.au3>
#include <GDIPlus.au3>
#include <GuiStatusBar.au3>
; Hide system tray icon
#NoTrayIcon
; Use Event mode
Opt("GUIOnEventMode", 1)
; Setup some constants
Const $ProgramName  = "InnoTab Thumbnail Editor"
Const $Version  = "v1.00"
Const $WindowTitle = $ProgramName & " " & $Version & " by NiVZ"
Const $REMOVABLE_DRIVES_NOT_FOUND = -1
Const $LLN_FOLDER_NOT_FOUND   = -2
; Global  Variables
Global $aResult, $iRows, $iColumns
Global $InnoTabDriveLetter = ""
Global $LLNPath = ""
Global $SQLDB
; Try to find what drive letter the InnoTab or SD card is using
Global $InnoTabDriveLetter = _FindInnoTabDriveLetter()
; For Debug - Put VideosInfo.db into C:\LLN
;Global $InnoTabDriveLetter = "C:"
If $InnoTabDriveLetter = $REMOVABLE_DRIVES_NOT_FOUND Then
   MsgBox(16, $WindowTitle, "Could not detect InnoTab or InnoTab SD card" & @CRLF & @CRLF & "Please ensure your InnoTab is connected to PC with an SD card inserted and is powered on OR alternatively insert your Innotab SD card directly into your PC")
   Exit
ElseIf $InnoTabDriveLetter = $LLN_FOLDER_NOT_FOUND Then
   MsgBox(16, $WindowTitle, "Could not find LLN folder on any removable drive" & @CRLF & "Please ensure InnoTab is connected and/or InnoTab SD Card is inserted")
   Exit
EndIf
; Now we have Drive Letter, setup some extra paths
$LLNPath   = $InnoTabDriveLetter & "\LLN"
$VideosInfoPath = $LLNPath & "\VideosInfo.db"
; Check videos database exists
If Not FileExists($VideosInfoPath) Then
    MsgBox(16, $WindowTitle, "Could not find VideosInfo.db in folder " & $LLNPath & @CRLF)
   Exit
EndIf

; ### Setup the User Interface ######
Global $Form   = GUICreate($WindowTitle, 480, 480)
Global $grpVideo  = GUICtrlCreateGroup("Video List", 10, 10, 310, 460)
Global $lvVideos  = GUICtrlCreateListView("Video Title",20,30,290, 430)
GUICtrlSetBKColor(-1, $GUI_BKCOLOR_LV_ALTERNATE)
_GUICtrlListView_SetColumnWidth(-1, 0, 269)
GUICtrlCreateGroup("", -99, -99, 1, 1) ;close group
Global $grpThumb = GUICtrlCreateGroup("Thumbnail", 335, 10, 130, 160)
Global $imgIcon  = GUICtrlCreatePic("", 355, 30, 88, 88, -1, $WS_EX_CLIENTEDGE)
Global $butChange = GUICtrlCreateButton("Change Thumbnail", 350, 128, 100, 30)
GUICtrlCreateGroup("", -99, -99, 1, 1) ;close group
$grpInnoTab  = GUICtrlCreateGroup("InnoTab Details", 335, 180, 130, 90)
$lblDriveLetter = GUICtrlCreateLabel("Drive: ", 354, 200, 30, 15)
$txtDriveLetter = GUICtrlCreateLabel("", 386, 200, 70, 15, $SS_RIGHT)
$lblLLNPath  = GUICtrlCreateLabel("LLN Folder: ", 354, 220, 90, 15)
$txtLLNPath  = GUICtrlCreateLabel("", 416, 220, 40, 15, $SS_RIGHT)
$lblNoOfVideos  = GUICtrlCreateLabel("No Of Videos: ", 354, 240, 70, 15)
$txtNoOfVideos = GUICtrlCreateLabel("", 426, 240, 30, 15, $SS_RIGHT)
GUICtrlCreateGroup("", -99, -99, 1, 1) ;close group
$grpAbout  = GUICtrlCreateGroup("About", 335, 280, 130, 190)
$lblAbout  = GUICtrlCreateLabel("", 345, 300, 110, 160)
GUICtrlSetData(-1, @CRLF & "For best results use square images." & @CRLF & @CRLF & "Images will be resized to InnoTab thumbnail size of 88 x 88 pixels." & @CRLF & @CRLF & "Special thanks to [email="Prog@ndy"]Prog@ndy[/email] and jchd for their help.")
;GUICtrlSetBkColor(-1, 0xFFFFFF)
GUICtrlCreateGroup("", -99, -99, 1, 1) ;close group
; ### End User Interface ###
; Handle GUI events
GUISetOnEvent($GUI_EVENT_PRIMARYDOWN,  "FormEvents")
GUICtrlSetOnEvent($butChange,    "ChangeImage")
GUISetOnEvent($GUI_EVENT_CLOSE,   "SpecialEvents")
GUISetOnEvent($GUI_EVENT_MINIMIZE,   "SpecialEvents")
GUISetOnEvent($GUI_EVENT_RESTORE,   "SpecialEvents")
; Update the InnoTab drive info
GUICtrlSetData($txtDriveLetter, $InnoTabDriveLetter)
GUICtrlSetData($txtLLNPath, $LLNPath)
_GDIPlus_Startup()
_SQLite_Startup()
; Try to open the SQL database
$SQLDB = _SQLite_Open($VideosInfoPath)
; Check database opened ok
If $SQLDB = 0 Then
   MsgBox(16, $WindowTitle, "Error opening database " & $VideosInfoPath)
   Exit
EndIf
; Select the values into an array
$iRval = _SQLite_GetTable2d(-1, "SELECT pkey,title FROM VideosInfo order by title;", $aResult, $iRows, $iColumns)
If $iRval = $SQLITE_OK Then
    ;_SQLite_Display2DResult($aResult)

; Check if any video details were returned
If $iRows = 0 Then
    MsgBox(48, $WindowTitle, "There does not appear to be any video files on your InnoTab")
    Else
  
   ; Add the videos title to the listview
   For $i = 1 To UBound($aResult)-1
   GUICtrlCreateListViewItem($aResult[$i][1], $lvVideos)
  
   ; Colour to use for alternating rows
   GUICtrlSetBKColor(-1, 0xEEEEEE)
   Next
  
   ; Highlight the first video
   _GUICtrlListView_SetItemSelected($lvVideos, 0)
  
   ; Get the thumbnail for the first video from the database
   ReadImageFromDB($aResult[1][0])
  
   ; Update InnoTab details with number of videos
   GUICtrlSetData($txtNoOfVideos, $iRows)
   EndIf
Else
   ; An error occurred while executing database query
   MsgBox(16, $WindowTitle, "Error querying database " & $VideosInfoPath)
   Exit
EndIf

; Show the GUI
GUISetState(@SW_SHOW)

; == MAIN PROGRAM ==============
While 1
   ; Wait for events
WEnd
; == MAIN PROGRAM ==============

; -- User Functions
Func ChangeImage()
  
   ; Check there is a row selected in the listview
   If _GUICtrlListView_GetSelectedCount($lvVideos) > 0 Then
  
   ; Get the selected row index
   Local $index  = _GUICtrlListView_GetSelectedIndices($lvVideos)+1
  
   ; Get the database primary key for this item
   Local $pKey   = $aResult[$index][0]
  
   ; Display a dialog to get an image filename
   Local $sFilename = FileOpenDialog("Choose Image...", @DesktopDir, "Images(*.jpg;*.png;*.bmp)", 3, "", $Form)
   If @Error Then
   ; Do nothing, dialog was cancelled
   Else
   ; Let user know we're updating as writing to InnoTab/SD card can be slow
   SplashTextOn($WindowTitle, "Please Wait - Updating Image", 350, 100, -1, -1, 33)
  
   ; Write this image to the database using the primary key
   WriteImageToDB($pKey, $sFilename)
  
   ; Let user know we're finished updating
   SplashOff()
   EndIf
  
   EndIf
  
   ; Return focus to the listview to keep selection highlighted
   ControlFocus($Form, "", $lvVideos)
  
EndFunc

Func WriteImageToDB($inPkey, $inFilename)
   ; Function written by [email="Prog@ndy"]Prog@ndy[/email] - many thanks
   Local $hLblDC = _WinAPI_GetDC(GUICtrlGetHandle($imgIcon))
   Local $hBitmap = _WinAPI_CreateCompatibleBitmap($hLblDC, 88, 88)
   Local $hDC = _WinAPI_CreateCompatibleDC($hLblDC)
   _WinAPI_SelectObject($hDC, $hBitmap)
  
   Local $hImg = _GDIPlus_ImageLoadFromFile($inFilename)
   Local $hGraph = _GDIPlus_GraphicsCreateFromHDC($hDC)
   _GDIPlus_GraphicsDrawImageRect($hGraph, $hImg, 0, 0, 88, 88)
   _GDIPlus_GraphicsDispose($hGraph)
   _GDIPlus_ImageDispose($hImg)
   Local $tData = DllStructCreate("byte[15488]")
   Local $tBITMAPINFOHEADER  = DllStructCreate("DWORD biSize;LONG  biWidth;LONG  biHeight;WORD  biPlanes;WORD  biBitCount;DWORD biCompression;DWORD biSizeImage;LONG  biXPelsPerMeter;LONG  biYPelsPerMeter;DWORD biClrUsed;DWORD biClrImportant; DWORD colormap[3]")
   DllStructSetData($tBITMAPINFOHEADER, 1, DllStructGetSize($tBITMAPINFOHEADER))
   DllStructSetData($tBITMAPINFOHEADER, 2, 88)
   DllStructSetData($tBITMAPINFOHEADER, 3, -88)
   DllStructSetData($tBITMAPINFOHEADER, 4, 1)
   DllStructSetData($tBITMAPINFOHEADER, 5, 16)
   ; use default GDI32 16 bit format: 5-5-5
   DllStructSetData($tBITMAPINFOHEADER,  6, 0)
   ; Choose Colormask manually, example for 5-5-5
   ;~ DllStructSetData($tBITMAPINFOHEADER,  6, 3) ;BI_BITFIELDS
   ;~ DllStructSetData($tBITMAPINFOHEADER, "colormap", 0x7C00, 1) ;- Red mask
   ;~ DllStructSetData($tBITMAPINFOHEADER, "colormap", 0x03E0, 2) ;- Green mask
   ;~ DllStructSetData($tBITMAPINFOHEADER, "colormap", 0x001F, 3) ;- Blue mask
   _WinAPI_GetDIBits($hLblDC, $hBitmap, 0, 88, DllStructGetPtr($tData), DllStructGetPtr($tBITMAPINFOHEADER), 1)
   _WinAPI_ReleaseDC(GUICtrlGetHandle($imgIcon), $hLblDC)
   _WinAPI_DeleteDC($hDC)
   _SQLite_Exec($SQLDB, "Update VideosInfo set thumbnail=x'" & Hex(DllStructGetData($tData, 1)) & "' where pkey='" & $inPkey & "';")
   _GUICtrlStatic_SetImage($imgIcon, $hBitmap)
  
EndFunc

Func ReadImageFromDB($inPkey)
  
   ; Function written by [email="Prog@ndy"]Prog@ndy[/email] - many thanks
  
   Local $aRow
   _SQLite_QuerySingleRow(-1, "SELECT thumbnail FROM VideosInfo where pkey='" & $inPkey & "'", $aRow)
   Local $hLblDC = _WinAPI_GetDC(GUICtrlGetHandle($imgIcon))
   Local $hBitmap = _WinAPI_CreateCompatibleBitmap($hLblDC, 88, 88)
   Local $hDC = _WinAPI_CreateCompatibleDC($hLblDC)
   _WinAPI_SelectObject($hDC, $hBitmap)

   Local $tData = DllStructCreate("byte[" & BinaryLen($aRow[0]) & "]")
   ;ConsoleWrite(BinaryLen($aRow[0]) & @CRLF)
   DllStructSetData($tData, 1, $aRow[0])
   Local $tBITMAPINFOHEADER  = DllStructCreate("DWORD biSize;LONG  biWidth;LONG  biHeight;WORD  biPlanes;WORD  biBitCount;DWORD biCompression;DWORD biSizeImage;LONG  biXPelsPerMeter;LONG  biYPelsPerMeter;DWORD biClrUsed;DWORD biClrImportant; DWORD colormap[3]")
   DllStructSetData($tBITMAPINFOHEADER, 1, DllStructGetSize($tBITMAPINFOHEADER))
   DllStructSetData($tBITMAPINFOHEADER, 2, 88)
   DllStructSetData($tBITMAPINFOHEADER, 3, -88)
   DllStructSetData($tBITMAPINFOHEADER, 4, 1)
   DllStructSetData($tBITMAPINFOHEADER, 5, 16)
   ; use default GDI32 16 bit format: 5-5-5
   DllStructSetData($tBITMAPINFOHEADER,  6, 0)
   ; Choose Colormask manually, example for 5-5-5
   ;~ DllStructSetData($tBITMAPINFOHEADER,  6, 3) ;BI_BITFIELDS
   ;~ DllStructSetData($tBITMAPINFOHEADER, "colormap", 0x7C00, 1) ;- Red mask
   ;~ DllStructSetData($tBITMAPINFOHEADER, "colormap", 0x03E0, 2) ;- Green mask
   ;~ DllStructSetData($tBITMAPINFOHEADER, "colormap", 0x001F, 3) ;- Blue mask
   _WinAPI_SetDIBits($hLblDC, $hBitmap, 0, 88, DllStructGetPtr($tData), DllStructGetPtr($tBITMAPINFOHEADER), 1)
   _WinAPI_ReleaseDC(GUICtrlGetHandle($imgIcon), $hLblDC)
   _WinAPI_DeleteDC($hDC)
   _GUICtrlStatic_SetImage($imgIcon, $hBitmap)
  
EndFunc

Func _FindInnoTabDriveLetter()
   Local $curDrive   = ""
   Local $arrRemDrives  = ""
   Local $Found   = False
   ; Get array of removable drives
   $arrRemDrives = DriveGetDrive("Removable")
   ;_ArrayDisplay($arrRemDrives)
  
   ; Check we found some removable drives
   If IsArray($arrRemDrives) Then
   ; Loop through removable drives looking for database LLN folder
   For $i = 1 To UBound($arrRemDrives)-1
   ; Set the current drive to the next value in the array
   $curDrive = StringUpper($arrRemDrives[$i])
   ; Look for the Learning Lodge Navigator folder
   If FileExists($curDrive & "\LLN") Then
   ; If it exists set FOUND to true and exit loop
   $Found = True
   ExitLoop
   EndIf
   Next
  
   If $Found Then
   ; Return the drive letter we found
   Return $curDrive
   Else
   ; Return that LLN folder was not found on any of the removable drives we scanned
   Return $LLN_FOLDER_NOT_FOUND
   EndIf
    
   Else
   ; No Removable Drives
   Return $REMOVABLE_DRIVES_NOT_FOUND
   EndIf
        
EndFunc
  
Func FormEvents()
   ; Get information from the control that is under the mouse pointer
   Local $cinfo =  GUIGetCursorInfo (WinGetHandle($Form))
   ; If the control is the listview and there is a row selected
   If $cinfo[4] = $lvVideos And _GUICtrlListView_GetSelectedCount($lvVideos) > 0 Then
   ; Get the selected row index
   Local $index  = _GUICtrlListView_GetSelectedIndices($lvVideos)+1
   ; Get the database primary key for this item
   Local $pKey  = $aResult[$index][0]
   ; Get the image from the database using the promary key
   ReadImageFromDB($pKey)
   EndIf
EndFunc

Func SpecialEvents()
    Select
        Case @GUI_CtrlId = $GUI_EVENT_CLOSE
            _SQLite_Shutdown()
   _GDIPlus_Shutdown()
            Exit
        ;Case @GUI_CtrlId = $GUI_EVENT_MINIMIZE
            ;MsgBox(0, "Window Minimized", "ID=" & @GUI_CtrlId & " WinHandle=" & @GUI_WinHandle)
        ;Case @GUI_CtrlId = $GUI_EVENT_RESTORE
            ;MsgBox(0, "Window Restored", "ID=" & @GUI_CtrlId & " WinHandle=" & @GUI_WinHandle)
    EndSelect
EndFunc   ;==>SpecialEvents

Func _GUICtrlStatic_SetImage($iCtrlId, $hBitmap)
  
   ; Function written by [email="Prog@ndy"]Prog@ndy[/email] - many thanks
  
   Local Const $STM_SETIMAGE = 0x0172
   Local Const $IMAGE_BITMAP = 0
   Local Const $SS_BITMAP = 0xE
   Local Const $GWL_STYLE = -16
   If IsHWnd($iCtrlId) Then
   If WinGetProcess($iCtrlId) <> @AutoItPID Then Return SetError(1,0,0)
   Else
   $iCtrlId = GUICtrlGetHandle($iCtrlId)
   If Not $iCtrlId Then Return SetError(2,0,0)
   EndIf
   ; set SS_BITMAP style to control
   Local $oldStyle = DllCall("user32.dll", "long", "GetWindowLong", "hwnd", $iCtrlId, "int", $GWL_STYLE)
   If @error Then Return SetError(3, 0, 0)
   DllCall("user32.dll", "long", "SetWindowLong", "hwnd", $iCtrlId, "int", $GWL_STYLE, "long", BitOR($oldStyle[0], $SS_BITMAP))
   If @error Then Return SetError(4, 0, 0)
   Local $oldBmp = DllCall("user32.dll", "handle", "SendMessageW", "hwnd", $iCtrlId, "int", $STM_SETIMAGE, "wparam", $IMAGE_BITMAP, "handle", $hBitmap)
   If @error Then Return SetError(5, 0, 0)
   If $oldBmp[0] Then _WinAPI_DeleteObject($oldBmp[0])
   Return 1
EndFunc

NiVZ

Link to comment
Share on other sites

Kudos, but you're taking that a bit too seriously (as far as I'm concerned and in my own opinion).

The one most important thing is that your kid daughter can look at pictures and click on what she wants with confidence.

Sharing that applet around can only make more little kids happier. That's what's important.

Then names are just ... names: sequences of symbols. Don't bother mentionning Volta, Maxwell, Lorentz, Plank, Bohr, Heisenberg, Shockley, Intel, Microsoft, Jon and the boundless multitude of scientists, engineers, technicians and volunteers who made all this possible at any rate. We all ride an implicit pyramid of giants and humble bricks.

I understand others can have a diverging opinion about the matter.

This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.
Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe here
RegExp tutorial: enough to get started
PCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta.

SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.
SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.
An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.
SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)
A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!
SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt)

Link to comment
Share on other sites

Thanks jchd :oops: Very humble of you. I tried to make the script as bullet proof as possible. Most parents using this device are not tech savvy and struggle to convert the videos in the first place so I tried to make this as crash proof as possible. Im lucky I can figure most things out but had to ask for help on this one and would feel bad calling this 'my' work when so much of the main functionality was figured out by you and Prog@ndy :doh: Credit where credit is due :bye:

Edited by NiVZ
Link to comment
Share on other sites

  • 1 month later...

Hello,

Sorry to resurrect this old thread. I've added a lot of new features to this program but have gotten stumped by another image problem.

I've added a 'Games' tab which use a different size thumbnail. From what I've figured out, this thumbnail is 57 pixels by 57 and uses the same format (except it has a small header giving the dimensions in hex 3900 0000 3900 0000, which I strip from the front)

The problem is when I read the rest of the image and display it, it is skewed (see attached image).

Would you guys mind having a look? I re-used Prog@ndys original code for a small test script and have attached the db file I'm using again.

Thanks,

NiVZ

#include<winapi.au3>
#include<sqlite.au3>
#include<windowsconstants.au3>
_SQLite_Startup()
_SQLite_Open(@ScriptDir & "\Innopad.db")
Global $aRow
_SQLite_QuerySingleRow(-1, "SELECT thumbnail FROM Games_info where pkey='3'", $aRow)
_SQLite_Close()
_SQLite_Shutdown()

GUICreate("Test")
$imgIcon = GUICtrlCreatePic("", 10, 10, 57, 57)
GUISetState()
$hLblDC = _WinAPI_GetDC(GUICtrlGetHandle($imgIcon))
$hBitmap = _WinAPI_CreateCompatibleBitmap($hLblDC, 57, 57)
$hDC = _WinAPI_CreateCompatibleDC($hLblDC)
_WinAPI_SelectObject($hDC, $hBitmap)

$aRow[0] = BinaryMid($aRow[0], 9, BinaryLen($aRow[0])-9)
ConsoleWrite($aRow[0] & @CRLF)
$tData = DllStructCreate("byte[" & BinaryLen($aRow[0]) & "]")
DllStructSetData($tData, 1, $aRow[0])
$tBITMAPINFOHEADER  = DllStructCreate("DWORD biSize;LONG  biWidth;LONG  biHeight;WORD  biPlanes;WORD  biBitCount;DWORD biCompression;DWORD biSizeImage;LONG  biXPelsPerMeter;LONG  biYPelsPerMeter;DWORD biClrUsed;DWORD biClrImportant; DWORD colormap[3]")
DllStructSetData($tBITMAPINFOHEADER, 1, DllStructGetSize($tBITMAPINFOHEADER))
DllStructSetData($tBITMAPINFOHEADER, 2, 57)
DllStructSetData($tBITMAPINFOHEADER, 3, -57)
DllStructSetData($tBITMAPINFOHEADER, 4, 1)
DllStructSetData($tBITMAPINFOHEADER, 5, 16)
; use default GDI32 16 bit format: 5-5-5
DllStructSetData($tBITMAPINFOHEADER,  6, 0)
; Choose Colormask manually, example for 5-5-5
;~ DllStructSetData($tBITMAPINFOHEADER,  6, 3) ;BI_BITFIELDS
;~ DllStructSetData($tBITMAPINFOHEADER, "colormap", 0x7C00, 1) ;- Red mask
;~ DllStructSetData($tBITMAPINFOHEADER, "colormap", 0x03E0, 2) ;- Green mask
;~ DllStructSetData($tBITMAPINFOHEADER, "colormap", 0x001F, 3) ;- Blue mask

_WinAPI_SetDIBits($hLblDC, $hBitmap, 0, 57, DllStructGetPtr($tData), DllStructGetPtr($tBITMAPINFOHEADER), 1)
_WinAPI_ReleaseDC(GUICtrlGetHandle($imgIcon), $hLblDC)
_WinAPI_DeleteDC($hDC)
_GUICtrlStatic_SetImage($imgIcon, $hBitmap)

While GUIGetMsg()<>-3
WEnd


; #FUNCTION# ====================================================================================================================
; Name...........: _GUICtrlStatic_SetImage
; Description ...: Sets a HBITMAP to a static control like image or label
; Syntax.........: _GUICtrlStatic_SetImage($iCtrlId, $hBitmap)
; Parameters ....: $iCtrlId  - CtrlId or handle of Control in the current process
;                 $hBitmap  - Pointer top Windows HBITMAP
; Return values .: Success    - 1
;                 Failure     - 0 and set @error:
;                 |1  - invalid $pSource
;                 |1  - invalid $pSource
; Author ........: ProgAndy, Zedna
; Modified.......:
; Remarks .......:
; Related .......:
; Link ..........:
; Example .......:
; ===============================================================================================================================
Func _GUICtrlStatic_SetImage($iCtrlId, $hBitmap)
    Local Const $STM_SETIMAGE = 0x0172
    Local Const $IMAGE_BITMAP = 0
    Local Const $SS_BITMAP = 0xE
    Local Const $GWL_STYLE = -16
    If IsHWnd($iCtrlId) Then
        If WinGetProcess($iCtrlId) <> @AutoItPID Then Return SetError(1,0,0)
    Else
        $iCtrlId = GUICtrlGetHandle($iCtrlId)
        If Not $iCtrlId Then Return SetError(2,0,0)
    EndIf
    ; set SS_BITMAP style to control
    Local $oldStyle = DllCall("user32.dll", "long", "GetWindowLong", "hwnd", $iCtrlId, "int", $GWL_STYLE)
    If @error Then Return SetError(3, 0, 0)
    DllCall("user32.dll", "long", "SetWindowLong", "hwnd", $iCtrlId, "int", $GWL_STYLE, "long", BitOR($oldStyle[0], $SS_BITMAP))
    If @error Then Return SetError(4, 0, 0)
    Local $oldBmp = DllCall("user32.dll", "handle", "SendMessageW", "hwnd", $iCtrlId, "int", $STM_SETIMAGE, "wparam", $IMAGE_BITMAP, "handle", $hBitmap)
    If @error Then Return SetError(5, 0, 0)
    If $oldBmp[0] Then _WinAPI_DeleteObject($oldBmp[0])
    Return 1
EndFunc

Innopad.zip

post-34043-0-89991300-1337783375_thumb.j

Link to comment
Share on other sites

Okay, I got a bit further and now realise this is to do with "Stride", but I still don't know how to fix it Posted Image

NiVZ

The amount of bytes per line must be a multiple of four. You currently have 3*57 = 171 bytes per line, so you have to insert one byte after each 171 bytes.

*GERMAN* [note: you are not allowed to remove author / modified info from my UDFs]My UDFs:[_SetImageBinaryToCtrl] [_TaskDialog] [AutoItObject] [Animated GIF (GDI+)] [ClipPut for Image] [FreeImage] [GDI32 UDFs] [GDIPlus Progressbar] [Hotkey-Selector] [Multiline Inputbox] [MySQL without ODBC] [RichEdit UDFs] [SpeechAPI Example] [WinHTTP]UDFs included in AutoIt: FTP_Ex (as FTPEx), _WinAPI_SetLayeredWindowAttributes

Link to comment
Share on other sites

  • 3 months later...

Hello,

Sorry to resurrect this old thread again.

I tried but never got this working. I'm now adding support for InnoTab 2 and though I'd give it another try.

This is as far as I got. I'm looping through the original thumbnail and adding a '00' byte after every 171 haracters which straightens it up a bit, but it's still slightly off.

#include<winapi.au3>
#include<sqlite.au3>
#include<windowsconstants.au3>
_SQLite_Startup()
_SQLite_Open(@ScriptDir & "Innopad.db")
Global $aRow
_SQLite_QuerySingleRow(-1, "SELECT thumbnail FROM Games_info where pkey='3'", $aRow)
_SQLite_Close()
_SQLite_Shutdown()
GUICreate("Test")
$imgIcon = GUICtrlCreatePic("", 10, 10, 57, 57)
GUISetState()
$hLblDC = _WinAPI_GetDC(GUICtrlGetHandle($imgIcon))
$hBitmap = _WinAPI_CreateCompatibleBitmap($hLblDC, 57, 57)
$hDC = _WinAPI_CreateCompatibleDC($hLblDC)
_WinAPI_SelectObject($hDC, $hBitmap)
$aRow[0] = BinaryMid($aRow[0], 9, BinaryLen($aRow[0])-9)
Dim $newRow

For $i = 1 To BinaryLen($aRow[0]) Step 171

ConsoleWrite("OLD:" & BinaryMid($aRow[0], $i, 171) & '00' & @CRLF)
$newRow &= BinaryToString(BinaryMid($aRow[0], $i, 171) & BinaryMid(0x00,1,2))
ConsoleWrite("NEW:" & BinaryMid($newRow, $i, 173) & @CRLF & @CRLF)

;EXITLOOP
Next
$newRow = Binary($newRow)
;ConsoleWrite("NEW ROW:" & @CRLF)
;ConsoleWrite($newRow & @CRLF)
;EXIT
;ConsoleWrite($aRow[0] & @CRLF)
;$tData = DllStructCreate("byte[" & BinaryLen($aRow[0]) & "]")
;DllStructSetData($tData, 1, $aRow[0])

MsgBox(0,"",BinaryLen($aRow[0]) & @CRLF & BinaryLen($newRow))
$tData = DllStructCreate("byte[" & BinaryLen($newRow) & "]")
DllStructSetData($tData, 1, $newRow)

$tBITMAPINFOHEADER = DllStructCreate("DWORD biSize;LONG biWidth;LONG biHeight;WORD biPlanes;WORD biBitCount;DWORD biCompression;DWORD biSizeImage;LONG biXPelsPerMeter;LONG biYPelsPerMeter;DWORD biClrUsed;DWORD biClrImportant; DWORD colormap[3]")
DllStructSetData($tBITMAPINFOHEADER, 1, DllStructGetSize($tBITMAPINFOHEADER))
DllStructSetData($tBITMAPINFOHEADER, 2, 57)
DllStructSetData($tBITMAPINFOHEADER, 3, -57)
DllStructSetData($tBITMAPINFOHEADER, 4, 1)
DllStructSetData($tBITMAPINFOHEADER, 5, 16)
; use default GDI32 16 bit format: 5-5-5
DllStructSetData($tBITMAPINFOHEADER, 6, 0)
; Choose Colormask manually, example for 5-5-5
;~ DllStructSetData($tBITMAPINFOHEADER, 6, 3) ;BI_BITFIELDS
;~ DllStructSetData($tBITMAPINFOHEADER, "colormap", 0x7C00, 1) ;- Red mask
;~ DllStructSetData($tBITMAPINFOHEADER, "colormap", 0x03E0, 2) ;- Green mask
;~ DllStructSetData($tBITMAPINFOHEADER, "colormap", 0x001F, 3) ;- Blue mask
_WinAPI_SetDIBits($hLblDC, $hBitmap, 0, 57, DllStructGetPtr($tData), DllStructGetPtr($tBITMAPINFOHEADER), 1)
_WinAPI_ReleaseDC(GUICtrlGetHandle($imgIcon), $hLblDC)
_WinAPI_DeleteDC($hDC)
_GUICtrlStatic_SetImage($imgIcon, $hBitmap)
While GUIGetMsg()<>-3
WEnd

; #FUNCTION# ====================================================================================================================
; Name...........: _GUICtrlStatic_SetImage
; Description ...: Sets a HBITMAP to a static control like image or label
; Syntax.........: _GUICtrlStatic_SetImage($iCtrlId, $hBitmap)
; Parameters ....: $iCtrlId - CtrlId or handle of Control in the current process
;                $hBitmap - Pointer top Windows HBITMAP
; Return values .: Success - 1
;                Failure     - 0 and set @error:
;                |1 - invalid $pSource
;                |1 - invalid $pSource
; Author ........: ProgAndy, Zedna
; Modified.......:
; Remarks .......:
; Related .......:
; Link ..........:
; Example .......:
; ===============================================================================================================================
Func _GUICtrlStatic_SetImage($iCtrlId, $hBitmap)
Local Const $STM_SETIMAGE = 0x0172
Local Const $IMAGE_BITMAP = 0
Local Const $SS_BITMAP = 0xE
Local Const $GWL_STYLE = -16
If IsHWnd($iCtrlId) Then
     If WinGetProcess($iCtrlId) <> @AutoItPID Then Return SetError(1,0,0)
Else
     $iCtrlId = GUICtrlGetHandle($iCtrlId)
     If Not $iCtrlId Then Return SetError(2,0,0)
EndIf
; set SS_BITMAP style to control
Local $oldStyle = DllCall("user32.dll", "long", "GetWindowLong", "hwnd", $iCtrlId, "int", $GWL_STYLE)
If @error Then Return SetError(3, 0, 0)
DllCall("user32.dll", "long", "SetWindowLong", "hwnd", $iCtrlId, "int", $GWL_STYLE, "long", BitOR($oldStyle[0], $SS_BITMAP))
If @error Then Return SetError(4, 0, 0)
Local $oldBmp = DllCall("user32.dll", "handle", "SendMessageW", "hwnd", $iCtrlId, "int", $STM_SETIMAGE, "wparam", $IMAGE_BITMAP, "handle", $hBitmap)
If @error Then Return SetError(5, 0, 0)
If $oldBmp[0] Then _WinAPI_DeleteObject($oldBmp[0])
Return 1
EndFunc

Thanks,

NiVZ

Edited by NiVZ
Link to comment
Share on other sites

  • 4 years later...
On ‎3‎/‎22‎/‎2012 at 11:20 AM, ProgAndy said:

BLOB-strings are enclosed in x'' in SQLite:

 

_SQLite_Exec($hDB, "INSERT OR REPLACE into Videos (thumbnail) VALUES (x'" & Hex(DllStructGetData($oData, 1)) & "');")

I am trying to read LONGBLOB data from a MySQL db, and then display it in an autoIT GUI. So something similar to this project, however I cannot seem to get this one to work so that I can try to retrofit it with ProgAndy's MySQL UDF. Any ideas? BTW, the issue is that when I save the attachment in an earlier post from test.txt to VideosInfo.db I get the error cannot open this database.

Link to comment
Share on other sites

You're likely to have much more success posting in some MySQL UDF thread, along with offending code.

This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.
Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe here
RegExp tutorial: enough to get started
PCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta.

SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.
SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.
An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.
SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)
A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!
SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt)

Link to comment
Share on other sites

12 hours ago, jchd said:

You're likely to have much more success posting in some MySQL UDF thread, along with offending code.

Thanks. I posted a much more thorough posting in the ProgAndy MySQL UDF thread, but I thought I would also take a chance here with trying to get this to even work with the code and attachements and I have had no success because of the attached file not opening up properly.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...