//--------------------------------------------------------------------------
// Parse the marker stream until SOS or EOI is seen;
//--------------------------------------------------------------------------
int ReadJpegSections (FILE * infile, ReadMode_t ReadMode)
{
    int a;
    int HaveCom = FALSE;

    a = fgetc(infile);

    if (a != 0xff || fgetc(infile) != M_SOI) {
        return FALSE;
    }

    ImageInfo.JfifHeader.XDensity = ImageInfo.JfifHeader.YDensity = 300;
    ImageInfo.JfifHeader.ResolutionUnits = 1;

    for(;;) {
        int itemlen;
        int prev;
        int marker = 0;
        int ll,lh, got;
        uchar * Data;

        if (!CheckSectionsAllocated()) return FALSE;

        prev = 0;
        for (a=0;; a++) {
            marker = fgetc(infile);
            if (marker != 0xff && prev == 0xff) break;
            if (marker == EOF) {
                ErrFatal("Unexpected end of file");
                return FALSE;
            }
            prev = marker;
        }

        if (a > 10) {
            ErrNonfatal("Extraneous %d padding bytes before section %02X",a-1,marker);
        }

        Sections[SectionsRead].Type = marker;

        // Read the length of the section.
        lh = fgetc(infile);
        ll = fgetc(infile);
        if (lh == EOF || ll == EOF) {
            ErrFatal("Unexpected end of file");
            return FALSE;
        }

        itemlen = (lh << 8) | ll;

        if (itemlen < 2) {
            ErrFatal("invalid marker");
            return FALSE;
        }

        Sections[SectionsRead].Size = itemlen;

        Data = (uchar *)malloc(itemlen);
        if (Data == NULL) {
            ErrFatal("Could not allocate memory");
            return FALSE;
        }
        Sections[SectionsRead].Data = Data;

        // Store first two pre-read bytes.
        Data[0] = (uchar)lh;
        Data[1] = (uchar)ll;

        got = fread(Data+2, 1, itemlen-2, infile); // Read the whole section.
        if (got != itemlen-2) {
            ErrFatal("Premature end of file?");
            return FALSE;
        }
        SectionsRead += 1;

        switch(marker) {

        case M_SOS:   // stop before hitting compressed data
            // If reading entire image is requested, read the rest of the data.
            if (ReadMode & READ_IMAGE) {
                int cp, ep, size;
                // Determine how much file is left.
                cp = ftell(infile);
                fseek(infile, 0, SEEK_END);
                ep = ftell(infile);
                fseek(infile, cp, SEEK_SET);

                size = ep-cp;
                Data = (uchar *)malloc(size);
                if (Data == NULL) {
                    ErrFatal("could not allocate data for entire image");
                    return FALSE;
                }

                got = fread(Data, 1, size, infile);
                if (got != size) {
                    ErrFatal("could not read the rest of the image");
                    return FALSE;
                }

                if (!CheckSectionsAllocated()) return FALSE;
                Sections[SectionsRead].Data = Data;
                Sections[SectionsRead].Size = size;
                Sections[SectionsRead].Type = PSEUDO_IMAGE_MARKER;
                SectionsRead ++;
                HaveAll = 1;
            }
            return TRUE;

        case M_DQT:
            // Use for jpeg quality guessing
            process_DQT(Data, itemlen);
            break;

        case M_DHT:
            // Use for jpeg quality guessing
            process_DHT(Data, itemlen);
            break;


        case M_EOI:   // in case it's a tables-only JPEG stream
            fprintf(stderr,"No image in jpeg!\n");
            return FALSE;

        case M_COM: // Comment section
            if (HaveCom || ((ReadMode & READ_METADATA) == 0)) {
                // Discard this section.
                free(Sections[--SectionsRead].Data);
            } else {
                process_COM(Data, itemlen);
                HaveCom = TRUE;
            }
            break;

        case M_JFIF:
            // Regular jpegs always have this tag, exif images have the exif
            // marker instead, althogh ACDsee will write images with both markers.
            // this program will re-create this marker on absence of exif marker.
            // hence no need to keep the copy from the file.
            if (memcmp(Data+2, "JFIF\0",5)) {
                fprintf(stderr,"Header missing JFIF marker\n");
            }
            if (itemlen < 16) {
                fprintf(stderr,"Jfif header too short\n");
                goto ignore;
            }

            ImageInfo.JfifHeader.Present = TRUE;
            ImageInfo.JfifHeader.ResolutionUnits = Data[9];
            ImageInfo.JfifHeader.XDensity = (Data[10]<<8) | Data[11];
            ImageInfo.JfifHeader.YDensity = (Data[12]<<8) | Data[13];
            if (ShowTags) {
                xprintf("JFIF SOI marker: Units: %d ",ImageInfo.JfifHeader.ResolutionUnits);
                switch(ImageInfo.JfifHeader.ResolutionUnits) {
                case 0:
                    xprintf("(aspect ratio)");
                    break;
                case 1:
                    xprintf("(dots per inch)");
                    break;
                case 2:
                    xprintf("(dots per cm)");
                    break;
                default:
                    xprintf("(unknown)");
                    break;
                }
                xprintf("  X-density=%d Y-density=%d\n",ImageInfo.JfifHeader.XDensity, ImageInfo.JfifHeader.YDensity);

                if (Data[14] || Data[15]) {
                    fprintf(stderr,"Ignoring jfif header thumbnail\n");
                }
            }

ignore:

            free(Sections[--SectionsRead].Data);
            break;

        case M_EXIF:
            // There can be different section using the same marker.
            if (ReadMode & READ_METADATA) {
                if (memcmp(Data+2, "Exif", 4) == 0) {
                    process_EXIF(Data, itemlen);
                    break;
                } else if (memcmp(Data+2, "http:", 5) == 0) {
                    Sections[SectionsRead-1].Type = M_XMP; // Change tag for internal purposes.
                    if (ShowTags) {
                        xprintf("Image cotains XMP section, %d bytes long\n", itemlen);
                        if (ShowTags) {
                            ShowXmp(Sections[SectionsRead-1]);
                        }
                    }
                    break;
                }
            }
            // Oterwise, discard this section.
            free(Sections[--SectionsRead].Data);
            break;

        case M_IPTC:
            if (ReadMode & READ_METADATA) {
                if (ShowTags) {
                    xprintf("Image cotains IPTC section, %d bytes long\n", itemlen);
                }
                // Note: We just store the IPTC section.  Its relatively straightforward
                // and we don't act on any part of it, so just display it at parse time.
            } else {
                free(Sections[--SectionsRead].Data);
            }
            break;

        case M_SOF0:
        case M_SOF1:
        case M_SOF2:
        case M_SOF3:
        case M_SOF5:
        case M_SOF6:
        case M_SOF7:
        case M_SOF9:
        case M_SOF10:
        case M_SOF11:
        case M_SOF13:
        case M_SOF14:
        case M_SOF15:
            process_SOFn(Data, marker);
            break;
        default:
            // Skip any other sections.
            if (ShowTags) {
                xprintf("Jpeg section marker 0x%02x size %d\n",marker, itemlen);
            }
            break;
        }
    }
    return TRUE;
}
Example #2
0
int main(int argc, char *argv[])
{
    //memcpy(self_client_id, "qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq", 32);
    
    if (argc < 4) {
        printf("usage %s ip port public_key\n", argv[0]);
        exit(0);
    }
    new_keys();
    printf("OUR ID: ");
    uint32_t i;
    for(i = 0; i < 32; i++) {
        if(self_public_key[i] < 16)
            printf("0");
        printf("%hhX",self_public_key[i]);
    }
    
    char temp_id[128];
    printf("\nEnter the client_id of the friend you wish to add (32 bytes HEX format):\n");
    if(scanf("%s", temp_id) != 1)
        exit(0);
    
    DHT_addfriend(hex_string_to_bin(temp_id));
    
    /* initialize networking */
    /* bind to ip 0.0.0.0:PORT */
    IP ip;
    ip.i = 0;
    init_networking(ip, PORT);
    

    perror("Initialization");
    IP_Port bootstrap_ip_port;
    bootstrap_ip_port.port = htons(atoi(argv[2]));
    /* bootstrap_ip_port.ip.c[0] = 127;
     * bootstrap_ip_port.ip.c[1] = 0;
     * bootstrap_ip_port.ip.c[2] = 0;
     * bootstrap_ip_port.ip.c[3] = 1; */
    bootstrap_ip_port.ip.i = inet_addr(argv[1]);
    DHT_bootstrap(bootstrap_ip_port, hex_string_to_bin(argv[3]));
    
    IP_Port ip_port;
    uint8_t data[MAX_UDP_PACKET_SIZE];
    uint32_t length;
    
    while(1) {
            
        process_DHT();
        
        while(receivepacket(&ip_port, data, &length) != -1) {
            if(DHT_handlepacket(data, length, ip_port) && friendreq_handlepacket(data, length, ip_port)) {
                //unhandled packet
                printpacket(data, length, ip_port);
            } else {
                printf("Received handled packet with length: %u\n", length);
            }
        }
        print_clientlist();
        print_friendlist();
        c_sleep(300);
    }
    
    shutdown_networking();
    return 0;   
}